2013-04-02 55 views
3

我對Unity和IoC稍微陌生,但對MVC不太熟悉。我一直在閱讀和閱讀關於在MVC中使用Unity以及我一直看到的唯一真正有用的東西是能夠使用控制器獲得免費的DI。MVC中的Unity DI有什麼好處?

要從此進入:

public HomeController() : this(new UserRepository()) 
    { 
    } 

    public HomeController(IUserRepository userRepository) 
    { 
     this.UserRepository = userRepository; 
    } 

要這樣:

public HomeController(IUserRepository userRepository) 
    { 
     this.UserRepository = userRepository; 
    } 

基本上,讓我砸無參數的構造函數。這真是太好了,所有這一切我都會實現,但是對於所有關於IoC庫的大肆宣傳來說,這似乎並不是什麼好事。將Unity用作服務定位器的方式聽起來很有吸引力,但很多人會認爲它是一種反模式。

所以我的問題是,有了服務定位問題和一些視圖和過濾器DI機會,還有什麼我從使用Unity獲得?我只是想確保我不會錯過像所有類構造函數一樣的免費DI支持。

編輯:

我理解其背後使用Unity DI與MVC控制器可測性的目的。但我所要做的只是添加一個額外的小構造函數,nix Unity,並且我可以將UnitTest完全一樣。當替代品更簡單時,註冊存儲庫類型和使用定製控制器工廠的好處在哪裏?替代方案是原生DI。我想我真的很想知道除了服務定位之外,Unity(或任何IoC庫)的優點是什麼,這很糟糕。自由控制器DI真的是我從Unity獲得的唯一東西嗎?

回答

0

沒有重點是你有一個映射的地方,指定了IUserRepository的具體類型。而你可能喜歡的原因是你可以創建一個UnitTest來指定一個IUserRepository的模擬版本並執行你的測試而不用改變控制器中的任何東西。

+0

但@Tim,我所要做的就是添加一個額外的小構造函數,nix Unity,並且我可以將UnitTest完全一樣。當替代品更簡單時,註冊存儲庫類型和使用定製控制器工廠的好處在哪裏? – Levitikon

0

大部分都是可測試性的,但是id建議看看Ninject,它在MVC中表現良好。爲了獲得IOC的全部好處,你應該真的將它與Moq或類似的模擬框架結合起來。

0

除了可測試性,我認爲你也可以將擴展性作爲優點之一。軟件開發的最佳實踐之一是「使用抽象而不是實現」,儘管可以通過多種方式實現,但Unity提供了一種非常易於擴展且易於實現的方法。通過使用這個,您將創建抽象,以定義您的組件必須遵守的合約。假設你想完全改變應用程序當前使用的Repository。使用DI,您只需「交換」組件,而無需更改應用程序中的單行代碼。如果您使用的是硬引用,則可能需要更改並重新編譯應用程序,因爲它的外部組件(位於不同層)

因此,使用DI的底線IMHO可幫助您獲得可插入組件在您的應用程序中有一個SOLID應用程序設計

1

一個好的IoC容器不僅爲您創建具體類,它還檢查該類型與其他類型之間的耦合。如果還有其他依賴項,則會解析它們並創建所有需要的類的實例。

你可以做一些花哨的事情,如條件綁定。下面是使用Ninject(我的首選IOC)的例子:

ninjectKernel.Bind<IValueCalculator>().To<LinqValueCalculator>(); 

ninjectKernel.Bind<IValueCalculator>().To<IterativeValueCalculator().WhenInjectedInto<LimitShoppingCart>(); 

什麼ninject是在這裏做注入LimitShoppingCart時候和任何其它注射用LinqValueCalulator的實例被創建IterativeValueCalculator的一個實例。

最大的好處是分離問題(解耦)和可測試性。

0

關於爲什麼服務定位器被認爲是不好的(有些人),你可以閱讀this blog-post by Mark Seeman

回答您的問題What is so good in Unity我可以說,除了所有的可測性,鬆散的耦合和其他等等,誇誇其談-S每個人都在談論你可以使用這樣真棒功能,像Unity's Interception它允許做一些AOP-like的東西。我在最近的一些項目中使用過它,並且非常喜歡它。強力推薦!

p.s.看起來像Castle Windsor DI容器也有類似的功能(稱爲攔截器)。其他容器 - 不確定。

1

除了測試(這是一個巨大的利益,不應該低估),依賴注入允許:

可維護性:改變你的代碼的行爲與一個變化的能力。

如果您決定更改在所有控制器/服務等中檢索用戶的類而無需依賴注入,則需要更新每個構造器以及任何正在創建的其他隨機新實例,前提是您記得在哪裏每個人都活着。 DI允許您更改一個在所有實現中使用的定義。

Scope:用一個單一的代碼行,你可以改變你的實現來創建一個單,即只在每一個新的Web請求或每一個新的線程

可讀性創建類:使用依賴注入意味着你所有的具體類都被定義在一個地方。作爲開發項目的開發人員,我可以快速而輕鬆地看到哪些具體類映射到哪些接口,並知道沒有隱藏的實現。這意味着我不僅可以更好地閱讀代碼,而且可以讓我有信心根據代碼進行開發。我相信使用依賴注入有助於創建設計良好的代碼。您自動代碼的接口,你的代碼變得更清潔,因爲你沒有得到的代碼塊怪幫你考

而且我們沒有忘記...

測試:測試是巨大的!依賴注入使您可以測試代碼,而無需專門爲測試編寫代碼。好的,你可以創建一個新的構造函數,但是阻止其他人使用該構造函數的目的不是爲了它的目的。如果另一位開發人員在六個月後出現,並將生產邏輯添加到「測試」構造函數中,該怎麼辦?好的,你可以使它成爲internal,但這仍然可以被生產代碼使用。爲什麼給他們選擇。

我的IoC框架經驗大部分在Ninject左右。因此,以上是基於我對Ninject的瞭解,但是相同的原則在其他框架中應該保持不變。

+0

您是否推薦過任何實施Unity DI的優秀開源項目?我希望看到另一個程序員結構並將其與我的結果進行比較,以便可能改進我的解決方案。 – JoshYates1980