2

好的。我終於理解了DI甚至IoC,容器等所有複雜的概念。但是我仍然錯過了一些東西。關於SOLID原則,使用容器和Unity的DI:如何管理容器中的DI映射?

假設我有一個名爲SomeClass的類,它將在構造函數中instaciate其中一個實現IFirstLevelOfAbstraction的類。執行IFirstLevelOfAbstraction的類是SubClass1SubClass2。我提到的那些類是instanciate實現ISecondLevelOfAbstraction的類,它們是SubClass3SubClass4

TL; DR這裏是圖像。

enter image description here

在我的入口點使用統一這應該是這個樣子:

IUnityContainer container = new UnityContainer(); 
container.RegisterType<SomeClass>(); 
container.RegisterType<IFirstLevelOfAbstraction, SubClass1>(); 
container.RegisterType<IFirstLevelOfAbstraction, SubClass2>(); 
container.RegisterType<ISecondLevelOfAbstraction, SubClass3>(); 
container.RegisterType<ISecondLevelOfAbstraction, SubClass4>(); 
var someClass= container.Resolve<SomeClass>(); 

問題是:如何選擇哪條路徑將DI必須在容器?

IFirstLevelOfAbstraction的實例是SubClass1ISecondLevelOfAbstractionSubClass4

稍後如何輕鬆更改此設置?

嵌套這麼多的DI不是反模式嗎?爲什麼?這爲什麼這麼好?

我覺得沒有人使用這個。在C#中它甚至不是本地的。

+1

是否'Class1'採取'IFirstLevelOfAbstraction'作爲構造函數的參數? –

+0

@YacoubMassad是的,它的確如此。 – Aoren

+4

扔掉你的DI容器,並採用[Pure DI](http://blog.ploeh.dk/2014/06/10/pure-di)代替;那麼您將自動能夠以您想要的方式完全配置您的依賴關係圖,而無需再學習其他類庫API。 –

回答

3

一種方式來做到這一點是不註冊SubClass1SubClass2SubClass3,或SubClass4然後選擇這種依賴,當你解決。這裏有一個例子:

IUnityContainer container = new UnityContainer(); 

var someClass = container.Resolve<SomeClass>(
    new DependencyOverride<IFirstLevelOfAbstraction>(new ResolvedParameter<SubClass1>()), 
    new DependencyOverride<ISecondLevelOfAbstraction>(new ResolvedParameter<SubClass4>())); 

如果這不是一個選擇(你不希望在指定的時間解決任何東西),你需要使用named registrations。我不會推薦去那條路線。

由於您對單個接口有多種實現,因此我建議您使用Pure DI。有一個原因請參見my article here

這裏是你的代碼將如何看起來像純DI:

var someClass = 
    new SomeClass(
     new SubClass1(
      new SubClass4())); 
+0

好的,讓我先閱讀你的文章,因爲我認爲容器方法應該「解決」使用這麼多嵌套構造函數(純DI)的需要。 – Aoren