通过枚举值+依赖注入创建实例

时间:2016-02-07 10:32:43

标签: c# dependency-injection enums factory

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

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()))));

1 个答案:

答案 0 :(得分:2)

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

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

另一个替代方案是inject a Func into the factory,因此您的DI容器可以解析实例。

将容器注入抽象工厂是制作framework extension point的一种方法。只要工厂是您composition root的一部分,这没关系。