2013-03-11 85 views
3

我已經閱讀IOC和Unity幾篇文章,並得到了我的自我困惑:(構造與控制器參數 - MVC

所以回到基本能有人電話我下面的代碼做什麼

private IStudent _student; 
     public HomeController(IStudent student) 
     { 
      _student= student; 
     } 

public interface IStudent 
    { 
     // Some method 
    } 

伊茨基本的,但我試圖從一個門外漢視圖來了解什麼上面完全相同的代碼呢?

+0

這是[Dependency Injection](http://martinfowler.com/articles/injection.html)的[構造函數注入](http://martinfowler.com/articles/injection.html#injector.gif)風格。 – publicgk 2013-03-11 06:11:38

回答

15

HomeController中對學生一個依賴,因爲它代表了一些責任Student類。實施

一種方法是:

public HomeController() 
{ 
    private Student _student; 
    public HomeController() 
    { 
     _student = new Student(); 
    } 
} 
public class Student 
{ 
    // Some method 
} 

但隨後的HomeController對學生類依賴。如果你想使用學生的其他實現(例如想要在單元測試HomeController的時候模擬學生),該怎麼辦?你將不得不修改學生類或HomeController類(或使用其他一些不那麼好的選擇)。這意味着你的HomeController的是緊耦合到Student類。

另一種方法是你已經發布的代碼:

public class HomeController 
{ 
    private IStudent _student; 
    public HomeController(IStudent student) 
    { 
     _student = student; 
    } 
} 
public interface IStudent 
{ 
    // Some method 
} 
public class Student : IStudent 
{ 
    // Implementation of some method 
} 

在這裏,你可以通過在IStudent即任何實現在單元測試中,你可以通過IStudent的模擬對象,在實際代碼將傳遞Student類的對象。所以你HomeController現在是依賴在IStudent接口(抽象)而不是在學生類(一個實現)。 這符合OOP原則:

編程爲接口,而不是實現。

取決於抽象。不要依賴於具體的課程。

此外,它現在具有軟依賴性。它不再與Student類緊密結合。它是鬆耦合。 現在,通常您不需要擔心在實例化您的HomeController時應該通過哪個IStudent實現。這就是Depedency Injection Container(你的情況下的Unity)會照顧到的,只要你註冊了正確的接口和類。

_container.Register<IStudent, Student>(); 

因此,當需要一個新的HomeController實例時,容器將識別需要一個IStudent實例。因此它將實例化IStudent的註冊實例,並在實例化HomeController類時將其作爲參數傳遞。

此外,請注意您所指的是'依賴注入'(這是IoC的一種特定形式)。還有其他形式的IoC(例如回調,觀察者模式等)。

編輯: 不要忘了閱讀DI上的popular article

+0

什麼是_container? – JAX 2014-08-30 11:59:24

+0

這是一個'依賴注入容器'。例如。 Unity([示例文章](http://msdn.microsoft.com/en-us/library/dn178463(v = pandp.30).aspx)),Castle Windsor,StructureMap等 – publicgk 2014-09-01 11:10:21

1

IOC中,你需要註冊這是實現該接口的接口和類。 所以一旦你那麼只要註冊你有簽名像上面那樣,IoC會自動創建一個IStudent實現類的實例,並在初始化控制器時將它注入到對象中。 它節省了宣佈成員的時間和努力。在上面的例子中,你只需要聲明一個,但它可能更多,並且可能需要更少的實例傳遞給控制器​​。 一旦我們完全正確地註冊IoC,之後就會開展工作。事實上,我們可以決定注入成員的範圍/生命週期。它可以是PerInstance/Per Request/Or Singleton。

有一些Saveral IoC框架可供您使用,您可以隨意使用它。

2

一般來說,它被稱爲注入類的依賴關係,思考一個類或精確的GOD類,它處理所有的東西(驗證用戶輸入,與數據庫協調,生成HTML輸出等),讓你保持你所有的代碼都在一個地方,或者你可以說你使用單個類來開發所有的軟件,這不是很好嗎?

答案取決於你組織事物的方式,你認爲組織它所屬的事物是有益的,而不是你在上面的GOD類中看到的問題。

所以在OOPS,單一類SHD方面必須改變單一的原因,但它需要得到比它做SHD採取的幫助服務工作。

和你的HomeController做,因爲它不希望同樣的事情被過度勞累,它已經要求學生對象來處理學生。

1

當一個新的HomeController目的通過IOC分解器構成,將需要的是實現由IOC容器(一個你註冊)通過它的構造提供IStudent接口的對象。

你可以閱讀更多關於Constructor Injection here.