2016-02-26 61 views
1

通常情況下,我會使用C#中的依賴注入容器(單位)這樣的例子:僅在應用程序啓動時使用DI容器?

class SomeClass 
{ 
    private readonly ILogger _logger; 

    public SomeClass() 
    { 
     _logger = DependencyContainer.Resolve<ILogger>(); 
    } 

    public void DoSomething() 
    { 
     var someOtherClass = DependencyContainer.Resolve<...>(); 
     someOtherClass().whatElseEver(); 
    } 
} 

昨天,我已經知道了正確的依賴注入二容器的一些文章。在此之後,我知道我的例子完全不好。這不是依賴注入,這只是一個服務定位器。

好的,該如何解決?我想與構造注入就可以輕鬆解決這個問題:

class SomeClass 
{ 
    private readonly ILogger _logger; 
    private readonly ISomeOtherClass _someOtherClass; 

    public SomeClass(ILogger logger, ISomeOtherClass someOtherClass) 
    { 
     _logger = logger; 
     _someOtherClass = someOtherClass; 
    } 

    public void DoSomething() 
    { 
     _someOtherClass().whatElseEver(); 
    } 
} 

現在我有正確執行的依賴注入的原則。 但如何連接所有這些依賴關係?我有一個呼叫者類解決類「SomeClass的」所需的全部decencies:

class SomeClassCaller 
{ 
    public void DoSomething() 
    { 
     var logger = DependencyContainer.Resolve<ILogger>(); 
     var someOtherClass = DependencyContainer.Resolve<...>(); 

     var someClass = new SomeClass(logger, someOtherClass); 
     someClass.DoSomething(); 
    } 
} 

但這個例子仍然使用依賴性容器作爲服務定位器,這是不好的。幾乎在每篇關於這個的文章中,我都讀過,應該只使用依賴容器,在應用程序的根/入口點,這是正確的嗎?

這意味着,沒有類應該有能力解決一些依賴與「服務定位器」的動態,如記錄器。我必須通過構造函數將ILogger注入幾乎每個類,以避免此問題,對嗎?這種方式感覺很糟糕,如果我把ILogger通過10個類加入到每個構造函數中,不是嗎?

所以,我只使用一個依賴容器,如果我有一個複雜的依賴關係圖?

有人可以給我一個例子,如果你使用一個依賴容器,它只是在應用程序的根目錄?

+0

請參閱[this](http://stackoverflow.com/questions/6277771/what-is-a-composition-root-in-the-context-of-dependency-injection)答案。關於這個完全相同的問題,還有很多這樣的問題。 – kayess

+0

你似乎對一般的東西有很好的處理。你必須立即做這件事的一件事就是在.NET中購買Mark Seemann的DI - 你不會後悔的;它將填補你的思維過程中的許多空白,以及一般的軟件架構。現在,對於你的實際問題,我不確定你在問什麼,但我有一個預感,這篇文章可能對你有用,以顯示如何將基本參數與對消費類沒有直接作用的基本參數分開:http ://docs.autofac.org/en/latest/advanced/delegate-factories.html –

回答

3

如果需要SomeClassCallerSomeClass,注入它:

public class SomeClassCaller 
{ 
    private readonly SomeClass someClass; 

    public SomeClassCaller(SomeClass someClass) 
    { 
     this.someClass = someClass; 
    } 

    public void DoSomething() 
    { 
     this.someClass.DoSomething(); 
    } 
} 

這是一個Concrete Dependency的一個例子。通常情況下,您可以讓SomeClass實現一個接口,然後將該接口注入SomeClassCaller,而不是具體的類。

Composition Root你就可以將你的對象圖:

var scc = new SomeClassCaller(
    new SomeClass(
     new MyLogger(), 
     new SomeOtherClass())); 

你並不需要一個DI容器要做到這一點,但您可以使用一個,如果你喜歡。

+0

謝謝你,這可以幫助我很多。在我們公司,我們完全使用IoC容器完成了依賴項注入,我們使用IoC容器作爲服務定位器。現在,我很清楚如何使用IoC容器,謝謝。 –

相關問題