2011-04-15 111 views
3

我在使用Munq作为MVC3项目中的DI容器。我有一个从存储库中检索DTO的服务层。根据该DTO中的属性,我需要使用两种策略之一在DTO上执行计算。我可以在容器中注册一个指定类型,例如C#依赖注入和策略模式

Container.Register<ICalculation>("Type1", c => new Type1Calculation); 
Container.Register<ICalculation>("Type2", c => new Type2Calculation); 

然后,当试图实例化适当的策略时,我可以直接引用容器。

var calc = Container.Resolve<ICalculation>(dto.ServiceType); 

但是,这使我对容器本身的依赖关系与相关的耦合和测试问题。我需要传递到服务构造函数中,以使我能够正确计算但不依赖于容器?我应该传递一个工厂,所以依赖关系在工厂而不在服务类中?

+0

作为更新上述情况,我目前使用和推荐SimpleInjector https://simpleinjector.org为DI 。一些优秀的背景信息可在https://cuttingedge.it/blogs/steven/pivot/entry.php?id=91 – 2015-08-09 20:43:28

回答

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

不确定Munq,但Autofac允许你绕过Func S,这样就可以完全跳过所有的工厂:

public class Foo 
{ 
    public Foo(Func<string, IBar> barFactory) { } 
} 

检查Munq允许这样的行为。

否则 - 是的,你将不得不诉诸手写工厂来提供另一个层次的间接。

+0

这在Autofac中如何工作?你传递一个Func给构造函数,在你的例子中是一个返回IBar的工厂。 Foo是服务类,它有一个Func来解决在我的情况下的计算?这是如何连接在Autofac容器中的? – 2011-04-15 08:29:46

+0

@David请参阅http://nblumhardt.com/2010/01/the-relationship-zoo/和http://code.google.com/p/autofac/wiki/RelationshipTypes。你不需要做任何特别的事情 - 几乎所有事情都是由Autofac自己完成的。 – 2011-04-15 12:34:39

+1

感谢Anton,但我仍然不完全确定这是如何“完全跳过所有工厂”。你的Func不是工厂吗?这比声明一个工厂类并在构造函数中注入它更好吗?你能提供一个barFactory Func的例子吗? – 2011-04-15 21:47:00