我的应用程序中有一些处理程序类是根据传递的枚举值在运行时创建的。它看起来像这样:
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();
}
}
}
对我来说没问题。但是如果我想像这样在我的处理程序中注入(inject)一些组件,这里就会出现问题:
public class SimpleHandler : IMyHandler
{
public SimpleHandler(IComponentOne c1, IComponentTwo c2, IComponentThree c3)
{
//...
}
public void Handle()
{
//logic here...
}
}
我用的是Unity IoC容器,当然想在这里用。但是在这里手动调用Resolve
方法看起来很难看。我走错路了吗?如何优雅地同时使用这两种模式?这里是在 facotry 中调用 IoC 容器的单一选项吗?
更新:我尝试在 InjectionFactory
类中使用委托(delegate)注入(inject)。它工作正常。但在这种情况下,如果我在两个应用程序中需要这样的工厂逻辑,我需要在两个应用程序启动时注册此委托(delegate)以及枚举和类之间的映射:
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 容器就可以解析实例。
将容器注入(inject)抽象工厂是制作 framework extension point 的一种方式.只要工厂是你的一部分composition root , 这没关系。
关于c# - 通过枚举值+依赖注入(inject)创建实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35252334/