有帮助吗?

解决方案

我认为你可以使用策略模式在这里。您可以保持枚举类型或使用任何类型,而不是帮助您识别策略(我将在我的示例中使用字符串)。然后实现每个值的策略。

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);
    }
}
.

您可以使用此类来获取正确的策略,具体取决于员工类型。这是我用DI容器实现策略模式的方式。它可以使用一些改进,我 很乐意听到一些建议。

其他提示

我一直在使用这个模式一段时间,但从未考虑过需要将服务注入其中。但嘿,应该是可能的吗?

一个解决方案是延迟创建依赖于服务实例的任何枚举,直到它们是必需的 - 其他一切仍然看起来并像常规静态类型一样。

这是EmployeeType类,添加了依赖于世代odicetagcode的Manager的延迟实例化:

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; } }
    }
}
.

,您可以在组合root中配置依赖项:

[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; } }
}
.


专门注入生成的原因,而不是世代odicetagcode,使得服务的寿命范围(以及装饰等)在组合根内管理并保持独立于消费者。

You could use a Singleton for your enum class.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top