Вопрос

Перед получением дие я был вполне поклонником использования так называемого класса ENUM (или сильный enum в моей голове), где перечисления превращаются в классы, но установленные для использования аналогичным образом.Это позволяет логике, которая действительно принадлежит к определенному Enum, чтобы заключаться в правильном месте и предотвращает множество беспорядков в базе кода.

Пример, который находится, который находится здесь http://lostechies.com/Jimmybogard / 2008/08 / 12 / классы перечисления /

Как только вы принесете ди уравнения, хотя он становится проблематичным из-за зависимости от статических переменных.

Есть ли способ продолжать поддерживать этот шаблон, а также использовать ди?

Редактировать: Вот пример типа, который является проблематичным, если я хочу ввести новую вещь в ShotingeType.Я не могу использовать контейнер из-за статических переменных.

public class EmployeeType : Enumeration
{
    public static readonly EmployeeType Manager 
        = new ManagerType (0, "Manager");
    public static readonly EmployeeType Servant 
        = new EmployeeType(1, "Servant");
    public static readonly EmployeeType AssistantToTheRegionalManager 
        = new EmployeeType(2, "Assistant to the Regional Manager");

    private EmployeeType() { }
    private EmployeeType(int value, string displayName) : base(value, displayName) { }
}

public class ManagerType : EmployeeType
{
}
.

Это было полезно?

Решение

Я думаю, что вы можете использовать Стратегический паттерн здесь.Вы можете сохранить свой тип Enum или использовать любой тип, чем может помочь вам определить стратегию (я буду использовать строку в моем примере).Затем реализуйте стратегию для каждого значения.

interface IEmployeeHandler
{
    string EmployeeType { get; }
    void Handle(Employee employee);
}

class ManagerHandler : IEmployeeHandler
{
    public ManagerHandler()
    {
        EmployeeType = "Manager";
    }

    public string EmployeeType { get; private set; }
    public void Handle(Employee employee) { }
}

class ServantHandler : IEmployeeHandler
{
    public ServantHandler()
    {
        EmployeeType = "Servant";
    }

    public string EmployeeType { get; private set; }
    public void Handle(Employee employee) { }
}
.

Поскольку DI-контейнеры могут вводить несколько реализаций интерфейса, вы можете написать класс поставщика стратегии, как это:

class EmployeeStrategyProvider
{
    private readonly IEmployeeHandler[] _employeeHandlers;

    public EmployeeStrategyProvider(IEmployeeHandler[] employeeHandlers)
    {
        _employeeHandlers = employeeHandlers;
    }

    public IEmployeeHandler GetStrategy(string employeeType)
    {
        return _employeeHandlers.FirstOrDefault(item => item.EmployeeType == employeeType);
    }
}
.

Вы можете использовать этот класс, чтобы получить правильную стратегию в зависимости от типа сотрудника.Вот как я реализую стратегическую узор с ди-контейнерами.Это может использовать некоторые улучшения, хотя я будет рад услышать некоторые предложения.

Другие советы

Я уже некоторое время использую этот шаблон, но никогда не учитывал необходимость ввести в нее услугу.Но эй, должно быть возможно, верно?

Одним из решений - отложить создание любых перечислений, которые зависят от экземпляра обслуживания, пока они не будут необходимы - все остальное все еще выглядит и действует как обычный статический тип.

Вот класс EmployeeType с добавлением задержки создаваемого генеракодицетагкода, который зависит от генеракодицетагкода:

public class EmployeeType : Enumeration
{
    public static Func<IBonusService> BonusService { private get; set; }

    private static EmployeeType _manager = null;
    public static EmployeeType Manager { 
        get 
        {
            if (_manager == null) _manager = new ManagerType(BonusService());
            return _manager;
        } }

    public static readonly EmployeeType Servant
        = new EmployeeType(1, "Servant");
    public static readonly EmployeeType AssistantToTheRegionalManager
        = new EmployeeType(2, "Assistant to the Regional Manager");
    private EmployeeType(int value, string displayName) :
       base(value, displayName) { }

    public virtual decimal BonusSize { get { return 0; } }

    private class ManagerType : EmployeeType
    {
        private readonly IBonusService service;
        public ManagerType(IBonusService service) : base(0, "Manager")
        {
            this.service = service;
        }

        public override decimal BonusSize {
            get { return this.service.currentManagerBonus; } }
    }
}
.

и вы настраиваете зависимости в корне композиции:

[Test]
public void EmployeeType_Manager_HasBonusService()
{
    Container container = new Container();
    container.Register<IBonusService, BonusServiceStub>();
    EmployeeType.BonusService = () => container.GetInstance<IBonusService>();

    BonusServiceStub.constructed = false;
    container.Verify();
    //Verify has ensured the container can create instances of IBonusService
    Assert.That(BonusServiceStub.constructed, Is.True);

    EmployeeType manager = EmployeeType.Manager;
    Assert.That(manager.BonusSize == 999m);
}


public class BonusServiceStub : IBonusService
{
    public static bool constructed = false;

    public BonusServiceStub() { constructed = true; }

    public decimal currentManagerBonus { get { return 999m; } }
}
.


Причина специально впрыскивая генеракодицетагкод вместо генеракодицетагкода, заключается в том, что срока службы (а также оформление и т. Д.) Управляется в корневой композиции и остается независимым от потребителя.

You could use a Singleton for your enum class.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top