從今天開始,我將和大家一起來學習這個控制反轉(Inversion of Control, IoC) 和依賴注入(Dependency Injection, DI) 容器的使用。關於 IoC 和 DI,大家可以參考 Martin Fowler 著的《IoC 容器和 Dependency Injection 模式》。
描述
Unity 應用程序塊(Unity)是一個輕量級、可擴展的依賴注入容器,支持構造函數、屬性和方法調用注入。它為開發人員提供了如下好處:
簡化了對象的創建,尤其是分層的對象結構和依賴。
允許開發人員在運行時或者配置中指定依賴的需求抽象,以及簡化了橫切關注點的管理。
服務定位功能允許客戶代碼保存或者緩存容器。這在開發人員可以持久化容器到 ASP.NET Session 或者 Application 中的 ASP.NET Web 應用程序中特別有用。
常見場景
除了單獨解決橫切關注點如日志、認證、授權、緩存和異常處理的組件以外,現代業務系統通常由定制的業務對象和在應用程序中完成特殊的或者一般的任務的組件組成。
成功構建這樣的應用程序的關鍵是獲得解耦的或者極度松耦合的設計。松耦合的應用程序更加靈活、更加易於維護。同時在開發期間進行測試,可以模擬對象的樁(輕量級模擬的實現),這增強了實質的依賴。例如,數據庫連接、網絡連接、ERP 連接和富用戶接口組件。
依賴注入是一種用於構建松耦合應用程序的主要技術。它提供了處理對象間依賴的方法。例如,一個處理用戶信息的對象可能依賴於訪問數據存儲、驗證信息和檢查用戶是否被授權執行更新的其他對象。依賴注入技術可以確保用戶類正確的初始化及組裝所有這些對象,特別是依賴是抽象的地方。
使用容器可以有很多好處,但它會改變應用程序的設計方式,尤其適合於基於組件的開發,朋友們可以有選擇的使用它。
最基本的代碼
下面的代碼展示了 Unity 容器的最基本的使用方法。
IUnityContainer myContainer = new UnityContainer();
myContainer.Register<IMyObject, MyRealObject>();
IMyObject myRealObjectInstance = myContainer.Get<IMyObject>();
在上面的代碼中,首先使用容器的 Register 方法注冊了一個 IMyObject 接口到 MyRealObject 具體類的類型映射(注:映射還可以通過配置文件來進行指定),然後通過 Get 方法來獲取 IMyObject 接口的默認映射所對應的具體對象實例。在這裡,IMyObject 接口被做為映射的鍵,Get 方法通過它來查找注冊的具體類的實例。
構造函數注入的代碼示例
假如,我們有如下的類定義:
public class MyObject {
public MyObject(MyDependentClass myInstance) {
myInstance.UserName = myInstance.ToString();
Console.WriteLine(string.Format("My name is {0}.", myInstance.UserName));
}
}
然後,利用容器,就可以這樣來實例化 MyObject 類的對象:
IUnityContainer uContainer = new UnityContainer();
MyObject myInstance = uContainer.Get<MyObject>();
Unity 容器會自動為 MyObject 對象創建 MyDependentClass 類的實例。
屬性(設置器)注入的代碼示例
例如,我們有如下的類定義:
public class MyObject {
private SomeOtherObject _dependentObject;
[Dependency]
public SomeOtherObject DependentObject {
get { return _dependentObject; }
set { _dependentObject = value; }
}
}
然後,使用與構造函數注入同樣的實例化代碼,Unity 容器就會自動為 MyObject 對象創建 SomeOtherObject 的對象實例。
IUnityContainer uContainer = new UnityContainer();
MyObject myInstance = uContainer.Get<MyObject>();
Console.WriteLine( string.Format(" Property injection object is {0}.",myInstance.DependentObject) );
Unity 應用程序塊的特性
它提供了用於構建(或者組合)對象實例的機制,對象可能包含其他依賴的對象實例。
它暴露了支持使用映射和對象(包括單件(singleton)實例)配置容器的 Register 方法,以及返回可以包含任何依賴的對象的構建對象實例的 Get 方法。
通過允許注入預配置的對象到由程序塊構建的類中來提供控制反轉(IoC)功能。開發人員可以在構造函數中指定接口或者類的類型(構造函數注入),或者用特性裝飾屬性和方法以初始化屬性注入和方法調用注入。
提供了用於容器的繼承層次。容器可能有子容器,允許將對象定位查詢從子容器傳遞到父容器中。
可以從標准配置系統如 XML 文件中讀取配置信息,並使用它來准備和配置容器。
不需要對象類的定義。不需要使用特性來裝飾類(使用屬性或者方法調用注入除外),無限制的類聲明。
支持開發人員可以實現的自定義容器擴展。例如,允許其他對象構建方法和容器特性,如緩存。
希望對您有所幫助!
本文配套源碼