2014-10-08 52 views
2

或者不是自己創建對象,而是以某種方式將它們攔截或掛鉤到對象創建(例如,由MVC框架實例化的Controller)並傳遞它們所需的任何依賴關係?DI容器是否需要自己實例化對象才能使用構造器注入?

我意識到他們需要做點什麼時才能使用構造器注入創建對象,但我不清楚該容器是否需要做創造,或者如果他們以某種方式攔截對象的創建。

無論答案是什麼,是否所有的DI容器都這樣做?

我認識到這一問題可能是有目共睹的最熟悉的像StructureMap,團結,Ninject等工具......但我是新來的他們,並意識到,我真的不知道他們在幕後是如何工作的。我搜索了互聯網,找不到一個好的答案。

+1

如果你的類接受他們的依賴關係通過構造函數參數,很難想象容器不會調用構造函數,因爲如何以其他方式獲取依賴項並正確初始化類。這在技術上是可行的,但只是調用構造函數就性能而言更容易,更安全和更快。 – Steven 2014-10-08 17:56:27

+0

@Steven:看到我的回答,容器並不需要直接調用構造函數。 – 2014-10-08 19:03:56

+0

@WiktorZychla:我讀了你的答案,我的評論可以被看作是對你答案的補充。我專門針對您*使用構造函數注入的情況。 – Steven 2014-10-08 19:06:43

回答

3

在我使用過的所有DI/IoC容器中,容器自己進行創建。您將不會使用new Something(dependency1, dependency2) ...找到任何生產代碼,您將有代碼隱式或明確地向容器請求「Something」的實例(可能是其他內容的依賴項)。然後,容器根據配置的方式(以及如何對Something進行註釋)來重新使用Something的實例。

如果你常顯式調用構造函數是在測試Something,此時容器很可能根本不存在 - 或者你可能有一個特定的測試配置,它允許你問一些庫存方式中的依賴關係,並可能以特定於測試的方式提供其他依賴關係。 (在某些情況下,仍然將不需要顯式調用構造函數...如果您有容器的測試配置,例如對所有內容使用虛擬存儲,那麼您可能仍然只需要請求一個Something在測試中使用。)

3

有至少三個略有不同的方法。

一個最常見的一種是當容器本身調用構造函數,使用某種反射和遞歸的方法來解決參數的。

然而,有時候,現有的實例(手動創建)被傳遞給容器,以構建它們,以滿足這些可以通過構造函數注入(否則這裏意味着「使用屬性注入」)滿足的依賴性。不過,這不可能是你問到的。

var foo = new Foo(new Bar()); 
container.BuildUp(foo); 

經常使用的最後一種方法是當一個工廠方法在容器中被登記。該容器不調用這個方法構造的話,相反,它會調用工廠方法和方法的人工實現,這意味着工廠的代碼直接調用構造函數:

container.RegisterType<IFoo>( 
    new InjectionFactory(c => new Foo(new Bar()))); 
相關問題