2010-07-15 75 views
3

這對大多數人來說似乎很明顯,但我只是想確認依賴注入(DI)依賴於接口的使用。依賴注入(DI)依賴於接口嗎?

更具體地說,對於在其構造函數中具有某個接口作爲參數的類或者定義爲屬性(又名Setter)的某個接口的情況下,DI框架可以移交具體類的實例以滿足該類接口的需求。 (道歉,如果這種描述不清楚,我無法正確描述這一點,因爲術語/概念對我來說還是一個新的東西。)

我問的原因是我目前有一個類有一個依賴排序。不是一個對象依賴關係,而是一個URL。這個類看起來是這樣的[C#]:

using System.Web.Services.Protocols; 
public partial class SomeLibraryService : SoapHttpClientProtocol 
{ 
     public SomeLibraryService() 
     { 
      this.Url = "http://MyDomainName.com:8080/library-service/jse"; 
     } 
} 

的SoapHttpClientProtocol類有一個名爲Url一個公共屬性(這是一個普通的老「串」),這裏的構造函數初始化它的硬編碼值。

我可以使用DI框架在施工時注入不同的值嗎?我想不是因爲this.Url不是Interface;這是一個String

[順便說一下,根據我正在使用的代碼中的註釋,上面的代碼是「由wsdl自動生成的」。所以我並不特別想改變這個代碼,儘管我沒有看到自己重新生成它。因此,也許改變這個代碼是好的。]

我可以看到自己製作的備用構造函數的字符串作爲參數,並初始化this.Url這種方式,但我不知道這是關於正確的方法保持鬆散耦合分離的擔憂。 (SoC)

針對這種情況的任何建議?

回答

6

它不需要使用接口 - 你可以使用具體類型或抽象基類。但是,在使用接口時,DI的許多優點(如能夠改變依賴性的實現)都會出現。

Castle Windsor(我最熟悉的DI框架)允許您將IoC容器中的對象映射到Interfaces或名稱,這可以在您的案例中起作用。

+0

我給你的綠色複選標記,但大衛和彼得的答案也很好。感謝您澄清接口不是必需的。 – Pretzel 2010-07-15 17:42:53

8

DI真的只是意味着一個類不會構造它的外部依賴關係,並且不會管理這些依賴關係的生命週期。依賴關係可以通過構造函數或通過方法參數注入。接口或抽象類型通常用於闡明消費者對其依賴關係的期望合約,但在某些情況下也可以注入簡單類型。

例如,庫中的一個類可能會在內部調用HttpContext.Current,這使得代碼將被託管在應用程序中的任意假設。庫方法的DI版本會希望通過參數注入HttpContext實例等

3

依賴注入是一種組織代碼的方式。也許你的一些混淆來自於沒有一種官方的方式來實現它。它可以通過使用「常規」c#代碼或使用Castle Windsor之類的框架來實現。有時(通常?)這涉及使用接口。無論如何實現,DI的總體目標通常是讓代碼更容易測試,並且稍後可以更容易地進行修改。

如果您要通過構造函數在您的示例中注入URL,那麼可以將其視爲「手動」DI。 DI上的維基百科article有更多手動與框架DI的例子。

+0

是的,我同意。有些混亂來自於那裏,沒有一個標準化的做法。 DI已經通過「Pro ASP.net MVC Framework」書籍(由Sanderson提供)呈現給我,並且每個示例都使用接口,所以我的結論是它只能在Interfaces上工作,但從邏輯上講,它在我的腦海中沒有意義,所以我不得不問。桑德森在他的第一本書中談到了溫莎城堡,但現在在他的第二版中使用了Ninject(上週剛剛從印刷機上脫穎而出。)是的,我開始意識到DI對單元測試有很大幫助。 – Pretzel 2010-07-15 17:47:27

1

我想重點關注在.NET應用程序中使用接口。 .NET中的多態性可以通過虛擬或抽象方法或接口來實現。

在所有情況下,都有一個方法簽名,根本沒有實現或者可以被覆蓋的實現。

定義了函數(甚至是屬性)的'契約',但是如何實現該方法,該方法的邏輯內容可以在運行時不同,由哪個子類實例化並傳入方法或構造函數,或設置屬性('注入'行爲)。

官方的.NET類型設計指導方針鼓吹在接口上使用抽象基類,因爲它們在發佈後有更好的選擇來發展它們,可以包括方便的重載,並且能夠更好地自我記錄並向實現者傳遞正確的用法。

但是,必須注意不要添加任何邏輯。這樣做的誘惑已經燒燬了過去許多人使用的接口 - 許多其他人使用接口,只是因爲程序員圍坐在他們身上。

有趣的是,雖然DI本身很少被過度使用,但是使用框架來執行注入通常被過度使用以增加複雜性的損害,鏈式反應可能發生在更多容器中需要更多類型,即使它們從未「切換」。

應該謹慎使用IoC框架,通常只有當您需要根據環境或配置在運行時交換對象時才需要使用IoC框架。這通常意味着切換應用程序中的主要組件「接縫」,例如用於抽象數據層的存儲庫對象。

對於我來說,IoC框架的真正威力在於在無法控制創建的地方切換實現。例如,在ASP.NET MVC中,控制器類的創建由ASP.NET框架執行,因此注入任何東西都是不可能的。 ASP.NET框架有一些鉤子,IoC框架可以用來在創建過程中「介入」並執行其魔術。

盧克