我的应用程序中有一些处理程序类,这些处理程序类是在运行时根据传递的枚举值创建的。看起来像这样:

public interface IMyHandler
{
    void Handle();
}

public class SimpleHandler : IMyHandler
{
    public void Handle()
    {
        //logic here...
    }
}

public class ComplexHandler : IMyHandler
{
    public void Handle()
    {
        //logic here...
    }
}

public enum HandlerTypes
{
    Simple,
    Complex
}

public class Hanlderfactory
{
    public IMyHandler CreateHandler(HandlerTypes type)
    {
        switch(type)
        {
            case HandlerTypes.Simple:
                return new SimpleHandler();
            case HandlerTypes.Complex:
                return new ComplexHandler();
            default:
                throw new NotSupportedException();
        }
    }
}


对我来说还好。但是如果我想在我的处理程序中注入一些组件,就会出现问题:

public class SimpleHandler : IMyHandler
{
    public SimpleHandler(IComponentOne c1, IComponentTwo c2, IComponentThree c3)
    {
        //...
    }

    public void Handle()
    {
        //logic here...
    }
}


我使用Unity IoC容器,当然我想在这里使用它。但是在这里手动调用Resolve方法看起来很丑。我走错了路吗?如何优雅地同时使用这两种模式?在工厂内部调用IoC容器是否是一种选择?
更新:我尝试使用InjectionFactory类的委托注入。工作正常。但是在这种情况下,如果我需要在两个应用程序中使用这种工厂逻辑,则需要在两个应用程序启动时都注册此委托以及枚举和类之间的映射:

var container = new UnityContainer();
container.RegisterType<IMyHandler, SimpleHandler>(HandlerTypes.Simple.ToString());
container.RegisterType<IMyHandler, ComplexHandler>(HandlerTypes.Complex.ToString());
container.RegisterType<Func<HandlerTypes, IMyHandler>>(new InjectionFactory(c => new Func<HandlerTypes, IMyHandler>(type => c.Resolve<IMyHandler>(type.ToString()))));

最佳答案

在工厂中使用Enum是一种代码味道,表明您需要进行更多的重构。

另一种选择是使用strategy pattern中的this example。请注意,使用Type而不是Enum确保设计更改时只需要更改一段代码即可(也可以使用字符串数据类型)。

另一种选择是inject a Func into the factory,以便您的DI容器可以解析实例。

将容器注入抽象工厂是制作framework extension point的一种方式。只要工厂是您的composition root的一部分,就可以了。

关于c# - 通过枚举值+依赖注入(inject)创建实例,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35252334/

10-15 16:19