2012-02-09 64 views

回答

4

我會添加一個解釋,我被告知是有幫助的。

正如你正確地指出,依賴注入是一類通過苛刻的構造函數或setter注入其合作者的行爲。你可以把它看作一種編碼技術。另一方面,控制反轉更多的是設計技巧 - 一種哲學,如果你願意的話。

在過程編程(在面向對象的語言過程式編程),您通常需要某種形式的「命令和控制」的理念。如果要創建由三個地板對象組成的房屋對象,每個對象由多個房間對象組成,則創建一個房屋對象,其構造函數實例化三個地板對象,每個對象的構造函數反過來實例化房間對象。

當您反轉控制,你倒指揮和控制模式。有了IoC,當我去實例化一棟房子時,它並沒有考慮到我所有的細節。相反,它說,通過它的構造函數(和依賴注入),「你不能在沒有一些地板的情況下實例化我」。所以,你去實例化地板,他們說「不,沒有一些房間」。現在,在這種「顛倒」的風格中,我們的房子並不控制房間的創造 - 它將其留給別人,而是表達出來,而僅僅是它會對房間給予的處理方式。這是可取的,因爲通過翻轉命令和控制它的頭部,你可以有更好的接口來推理和測試代碼 - 將事物解構成組件更容易。

因此,要總結,控制反轉是理念和依賴注入是通過它的實現的裝置。

5

我強烈建議您閱讀Dependency Injection in .NET這本書,它詳細介紹了全面的代碼示例。對於控制的倒置,你應該參考Robert Martin的另一本書:Agile Principles, Patterns, and Practices in C#。它詳細介紹了帶有示例和可理解解釋的SOLID原則。這兩本書確實幫助我理解了這些原則。

+0

+1 for SOLID。我採訪了很多無法回答這些原則基本問題的人。 – Ian 2012-02-09 21:36:59

6

比方說,你有一個需要服務類:

public class A 
{ 
    IEmailSender _emailSender 
    public A(IEmailSender emailSender) 
    { 
    _emailSender = emailSender; 
    } 

    private void SendEmail() 
    { 
    _emailSender.Send(); 
    } 
} 

一個現在據說已經在IEMailSender的依賴,這意味着它需要實現IEMailSender能夠執行它是一個對象功能。

像ninject或autofac依賴注入框架將負責創建實現IEMailSender對象並將其注入的一個構造,只要你告訴他們如何創建這樣的對象。使用ninject

例:

Bind<IEmailSender>().To<EmailSender>(); 

這是告訴ninject,每當一個類需要一個IEMailSender,給他們EmailSender(假設ofcourse該EmailSender實現IEMailSender接口)

這是我的簡單可以想到,希望這有助於。

+0

很好。你如何在這段代碼中使用容器類? – 2017-05-05 06:19:25

2

DI是IoC。控制反轉意味着交換誰決定如何實現任務。

在你過去的世界裏,你可能會創建一個名爲Logger的類和一個名爲LogTime()的類。唯一的目的是將當前時間寫入文件。

public void LogTime() 
{ 
    WriteToFile(GetCurrentTime()); 
} 

這裏的類有一個名爲WriteToFile和GetCurrentTime的方法。 IoC只是意味着,而不是Logger類決定如何寫入文件,甚至是獲取當前時間,您可以讓外部提供者提供這些詳細信息。

這就是DI進來的地方。您注入一個依賴關係。該方法依賴於寫入文件並獲取當前時間的手段。你注入這些方法。

DI有兩種常見的屬性注入和構造函數注入模式。他們在錫上做他們所說的話。如何做到注入的特定框架。

一些使用屬性,一些使用配置文件。有些採取最佳猜測方法。

沿邊DI你有SL(服務定位),這就好比是禮貌DI。在DI中,你會說「採取這種依賴並喜歡它」。有了SL,上面的Logger類會說:「請問可以有些東西來填補這個依賴關係嗎?」。看到?有禮貌。

使其工作的核心是接口。 LogToFile可能是ILogsToFiles接口上的一種方法。然後你可以有六個不同的接口實現,並注入最合適的。

有跡象表明,管理這一切都爲您提供框架的負荷,但一個簡單的服務定位是代碼10行,一個簡單的DI大概不超過兩倍。儘管你很快就會開始需要額外的東西。看看Ninject。我推薦它純粹是因爲它小而簡單,可能是一個很好的起點。