我在MVC3项目中使用Munq作为DI容器。我有一个服务层,可以从存储库中检索DTO。根据DTO中的属性,我需要使用两种策略之一来对DTO执行计算。我可以在容器中注册一个命名类型,例如
Container.Register<ICalculation>("Type1", c => new Type1Calculation);
Container.Register<ICalculation>("Type2", c => new Type2Calculation);
然后我可以在尝试实例化适当的策略时直接引用容器,例如
var calc = Container.Resolve<ICalculation>(dto.ServiceType);
但这让我依赖于容器本身以及相关的耦合和测试问题。我需要传递给服务构造函数,这将允许我获得正确的计算,但不依赖于容器?我是否应该传入工厂,因此依赖项是在工厂而不是在服务类中?
答案 0 :(得分:5)
不确定Munq,但Autofac允许您传递Func
s,以便您可以完全跳过所有工厂:
public class Foo
{
public Foo(Func<string, IBar> barFactory) { }
}
检查Munq是否允许这种行为。
否则 - 是的,你将不得不诉诸手写工厂来提供另一层次的间接。
答案 1 :(得分:0)
我已经为此添加了Munq解决方案。首先包含 IDependencyResolver 接口的工厂允许工厂使用容器来解析工厂方法中的依赖关系:
public class CalculationFactory
{
private readonly IDependencyResolver _resolver;
public CalculationFactory(IDependencyResolver resolver)
{
ThrowIfNullArgument(resolver, "resolver", typeof(IDependencyResolver));
_resolver = resolver;
}
public static ICalculation CreateCalculator(int serviceType)
{
switch (serviceType)
{
case 1: return _resolver.Resolve<ICalculation>("Type1");
case 2: return _resolver.Resolve<ICalculation>("Type2");
default: return _resolver.Resolve<ICalculation>("InvalidType");
}
}
}
然后在Global.asax.cs中注册相应的接口/类,将容器传递给工厂。所以现在我可以设置我的测试,并且工厂内唯一的额外依赖是 IDependencyResolver :
ioc.Register(c => new CalculationFactory(c));
ioc.Register<ICalculation>("Type1", c => c.Resolve<Type1Calculation>());
ioc.Register<ICalculation>("Type2", c => c.Resolve<Type2Calculation>());
ioc.Register<ICalculation>("InvalidType", c => c.Resolve<InvalidCalculation>());