原文連結:http://www.doriandeng.cn/archives/95.html。
Unity 是由微軟開發的一個輕量級、可擴充的依賴注入(Dependency Injection, DI)容器,支援建構函式、屬性和方法的依賴注入。所謂依賴的注入,即將程式開發過程中的對象與其所依賴的具體對象解耦,從一定程度上僅關注對所依賴對象 的使用,卻不管其具體對象是哪個類的執行個體;而真正的被依賴對象在運行時由容器注入。本質上,它就是一個對象工廠和對象管理器。更詳細的資訊,請參見 《IoC 容器和Dependency Injection 模式》。
Unity 適用於可擴充、可插接的應用程式的開發,對於普通的、不要求插接的應用程式的開發反而會增加開發的複雜度。Unity 的使用對效能也會有少量的影響 。
準備
在本系列的文章中,我們假設有一個 Telephone 類,一個 IDialer 介面和一個 Dialer 抽象類別。如下代碼所示:
Unity 的初始化
Unity 容器在使用前一般需要針對所使用的物件類型進行初始化,某些時候也可以不進行初始化。Unity 容器的初始化主要是物件類型的註冊。這可以用二種方法完成,一是使用 .NET 代碼,另一種就是使用 XML 設定檔。在 Unity 文檔的樣本中,絕大多數的樣本都是使用代碼的方法來對 Untiy 進行初始化,這也給不少人造成了使用 Unity 容器來管理對象比直接使用更複雜的錯覺。本文將同時使用代碼和 XML 設定檔的方法來對初始化及其其他相關方面進行說明,以便大家對 Unity 能有更全面、更正確的認識。
類型註冊
首先,在代碼檔案中添加對 Microsoft.Practices.Unity 命名空間的引用。
然後,可以用代碼方式進行如下的註冊,(其中的 ButtonTypeDialer 類包含在供下載的原始碼中。):
運行結果如下:
下面,我們看看用 XML 如何來進行初始化。
首先,在設定檔中,需要添加下列配置節聲明:
然後,配置類型註冊:
最後,我們可以用下列的方式來使用:
由上面的代碼我們可以看出,在完成 Unity 的容器初始化後,使用的方法是一樣的。
建構函式注入
實質上,上面的樣本我們可以用如下代碼來實現:
這二段代碼唯一的不同就是 38、39 行合并成了 52 這一行。這就是利用了建構函式注入。
在 Telephone 類中,我們聲明了一個 public Telephone(IDialer dialer) 的建構函式,而在 Unity 容器中,已進行了用於 IDialer 介面的註冊,所以在使用 Unity 容器的 Resolve 方法擷取對象時,就自動調用了此建構函式對對象進行了初始化。如果不存在這樣的建構函式,Unity 容器將自動調用其預設建構函式進行初始化。
如果同時存在多個帶參數的建構函式,就需要用 [InjectionConstructor] 特性來指定將使用的建構函式。
屬性注入
要使用屬性注入,我們需要在 Telephone 類的 Dialer 屬性上加上 [Dependency] 特性聲明,如下所示:
同時,在設定檔中加入如下配置以註冊 Dialer 抽象類別的映射:
這樣,建構函式注入中的範例程式碼就依然是有效,雖然建構函式已被注釋掉了。
方法調用注入
我們對 Telephone 類做進一步的修改,注釋掉 [Dependency] 特性,添加一個 Initialize 方法:
在 Initialize 方法上,我們加上了 [InjectionMethod] 以指出使用了方法調用注入的方法。這也使得在建構函式注入中所使用的範例程式碼依然有效。
總結
Unity 是一個輕量級、可擴充的 DI 容器,它可以用代碼或設定檔來進行類型的註冊,同時支援建構函式注入、屬性注入和方法調用注入。
原始碼下載
look-into-unity-1-x.zip
理想&美人