2011-04-15 123 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