IoC 是什么?
在軟件工程領域,“控制反轉(Inversion of Control,縮寫為IoC)”是一種編程技術,表述在面向對象編程中,可描述為在編譯時靜態分析器並不知道具體被耦合的對象,而該對象是在運行時被對象裝配器綁定的。
在傳統編程中,決定業務流程的對象是被靜態分配的。而在 IoC 中,業務流程取決於對象裝配器實例化提供的對象,這使利用抽象來定義對象間的交互成為可能。對象裝配器為了能綁定一個對象,要求該對象必須具備兼容的抽象定義。例如類 ClassA 可以需要接口 InterfaceI 的功能,而 ClassB 實現了該接口,則裝配器可實例化 ClassA 和 ClassB,並將 ClassB 的實例注入到 ClassA 的實例中。
在實踐中,IoC 是一種利用可復用代碼來控制特性需求代碼的軟件構建風格。它着重強調了在應用程序的開發中,可復用代碼和特性需求代碼可分別被獨立地實現。
IoC 作為一種軟件設計准則有以下用途:
- 將某項任務的執行從具體實現中解耦和。
- 各個模塊可專注於其設計目的。
- 模塊僅依賴於契約定義,不會對具體實現做出任何假設。
- 更換模塊對其他模塊沒有任何副作用。
IoC 還時常被稱為著名的 "好萊塢原則":
Hollywood Principle: Don't call us, we'll call you.
在好萊塢,當演員把簡歷遞交給演藝公司之后,經常得到的答復是 "不要來找我們,需要時我們會找你的。",演員只能被動式的接受公司的差使,在需要的環節完成自己的演出。
IoC 實現技術
在面向對象編程中,有多種基本技術可實現 IoC:
- 使用工廠模式 FactoryPattern
- 使用 ServiceLocator 模式
- 使用依賴注入 DependencyInjection
IoC 是非常通用的技術術語,IoC的擁護者提倡使用更為特定的名稱“依賴注入(Dependency Injection,縮寫為 DI)”來描述。
IoC容器是什么?
IoC 容器是一種管理對象創建過程的簡單方式。可以通過它來定義復雜對象的創建過程,使你可以通過幾行代碼即可獲取到所需的對象。也可使用它來為類和方法注入(Inject)依賴項。
IoC 容器可以提高應用程序的靈活行和可測試行。通過在容器中注冊接口實現的替代實現,或使用 Stub 和 Mock 等技術來隔離被測試代碼的外部依賴。
Unity是什么?
Unity 是一個輕量級、可擴展的依賴注入容器(Dependency Injection Container),其支持截取、構造函數注入、屬性注入和方法調用注入等。可以利用 Unity 通過多種方式進行應用程序組件間的解耦,從而最大化組件的一致性,並簡化設計、實施、測試和管理等。
Unity 提供了所有常見的依賴注入機制,包括注冊類型映射、注冊對象實例、解決依賴、管理對象的生存期,為參數的構造函數和方法注入依賴對象,和解析對象的屬性值。 此外,Unity 擁有很好的可擴展性。可以通過添加容器擴展來改變容器的行為或增加新的功能。例如在 Unity 中攔截功能,向被攔截對象添加各種策略即是通過容器擴展實現。
Unity的設計目標
- 通過促進模塊化的設計原則來解除組件、業務對象和服務間的耦合;
- 提高在設計應用程序時最大化可測試性的意識;
- 提供用於創建和管理對象的快速輕量的依賴注入容器機制;
- 為開發者提供緊湊和直觀的 API;
- 支持寬泛的編程語言特性,例如通過方法覆寫來支持泛型參數;
- 為構造函數、屬性和方法實現特性驅動的注入;
- 提供自定義和第三方的容器擴展機制;
- 滿足企業級 LOB 應用程序中性能需求;
Unity可以做什么?
通過使用 DI 框架和 IoC 機制,可以生成或裝配類和對象的實例,並且該實例可以包含所依賴的對象實例和設置。
- 創建指定類型的對象
- 注冊現有類型或對象實例
- 管理對象的生存期
- 注入指定對象
- 填充或注入數組
- 攔截對對象的調用
Unity構造函數注入代碼示例
如果使用 Unity 實例化一個類,該類的構造函數依賴一個或多個其他類,則 Unity 會為構造函數自動創建參數中指定的被依賴的類的實例。
例如,下面的代碼展示了一個名為 "CustomerService" 的類,其構造函數的入參依賴於一個名為 "LoggingService" 的類。
public class CustomerService { public CustomerService(LoggingService log) { log.WriteToLog("I'm an injected concrete logging service."); } }
在運行時,可使用 Unity 容器的 Resolve 方法創建 "CustomerService" 類的實例,則一個 "LoggingService" 類的具體實現會被注入到 "CustomerService" 實例中。
IUnityContainer container = new UnityContainer(); CustomerService customer = container.Resolve<CustomerService>();