解構控制反轉(IoC)和依賴注入(DI)
解構控制反轉(IoC)和依賴注入(DI)
1.控制反轉
控制反轉(Inversion of Control,IoC),簡言之就是程式碼的控制器交由系統控制,而不是在程式碼內部,透過IoC,消除元件或者模組間的直接依賴,使得軟體系統的開發更具柔性和擴充套件性。控制反轉的典型應用體現在框架系統的設計上,是框架系統的基本特徵,不管是.NET Framework抑或是Java Framework都是建立在控制反轉的思想基礎之上。
控制反轉很多時候被看做是依賴倒置原則的一個同義詞,其概念產生的背景大概來源於框架系統的設計,例如.NET Framework就是一個龐大的框架(Framework)系統。在.NET Framework大平臺上可以很容易地構建ASP.NET Web應用、Silverlight應用、Windows Phone應用或者Window Azure Cloud應用。很多時候,基於.NET Framework構建自定義系統的方式就是對.NET Framework本身的擴充套件,呼叫框架提供的基礎API,擴充套件自定義的系統功能和行為。然而,不管如何新建或者擴充套件自定義功能,程式碼執行的最終控制權還是回到框架中執行,再交回應用程式。黃忠誠先生曾經在Object Builder Application Block一文中給出一個較為貼切的舉例,就是在Window From應用程式中,當Application.Run呼叫之後,程式的控制權交由Windows Froms Framework上。所以,控制反轉更強調控制權的反轉,體現了控制流程的依賴倒置,所以從這個意義上來說,控制反轉是依賴倒置的特例。
2.依賴注入
依賴注入(Dependency Injection,DI),早見於Martin Flower的Inversion of Control Containers and the Dependency Injection pattern一文,其定義可概括為:
客戶類依賴於服務類的抽象介面,並在執行時根據上下文環境,由其他元件(例如DI容器)例項化具體的服務類例項,將其注入到客戶類的執行時環境,實現客戶類與服務類例項之間鬆散 的耦合關係。
(1)常見的三種注入方式
簡單而言,依賴注入的方式被總結為以下三種。
· 介面注入(Interface Injection),將物件間的關係轉移到一個介面,以介面注入控制。
首先定義注入的介面:
public interface IRunnerProvider
{
void Run(Action action);
}
為注入的介面實現不同環境下的注入提供器,本例的系統是一個後臺處理程式提供了執行環境的多種可能,預設情況下將執行於單獨的執行緒,或者透過獨立的Windows Service程式執行,那麼需要為不同的情況實現不同的提供器,例如:
public class DefaultRunnerProvider : IRunnerProvider
{
#region IRunnerProvider Members
public void Run(Action action)
{
var thread = new Thread(() => action());
thread.Start();
}
#endregion
}
對於後臺服務的Host類,透過配置獲取注入的介面例項,而Run方法的執行過程則被注入了介面所定義的邏輯,該邏輯由上下文配置所定義:
public class RunnerHost : IDisposable
{
IRunnerProvider provider = null;
public RunnerHost()
{
// Get Provider by configuration
provider = GetProvider(config.Host.Provider.Name);
}
public void Run()
{
if (provider != null)
{
provider.Run(() =>
{
// exceute logic in this provider, if provider is DefualtRunnerProvider,
// then this logic will run in a new thread context.
});
}
}
}
接口注入,為無須重新編譯即可修改注入邏輯提供了可能,GetProvider方法完全可以透過讀取配置檔案的config.Host.Provider.Name內容,來動態地建立對應的Provider,從而動態地改變BackgroundHost的Run()行為。
· 構造器注入(Constructor Injection),客戶類在型別構造時,將服務類例項以建構函式引數的形式傳遞給客戶端,因此服務類例項一旦注入將不可修改。
public class PicWorker
{
}
public class PicClient
{
private PicWorker worker;
public PicClient(PicWorker worker)
{
// 透過構造器注入
this.worker = worker;
}
}
· 屬性注入(Setter Injection),透過客戶類屬性設定的方式,將伺服器類例項在執行時設定為客戶類屬性,相較構造器注入方式,屬性注入提供了改寫伺服器類例項的可能。
public class PicClient
{
private PicWorker worker;
// 透過屬性注入
public PicWorker Woker
{
get { return this.worker; }
set { this.worker = value; }
}
}
另外,在.NET平臺下,除了Martin Flower大師提出的三種注入方式之外,還有一種更優雅的選擇,那就是依靠.NET特有的Attribute實現,以ASP .NET MVC中的Action Filter為例:
[HttpPost]
public ActionResult Register(RegisterModel model)
{
// 省略註冊過程
return View(model);
}
其中,HttpPostAttribute就是透過Attribute方式為Register Action注入了自動檢查Post請求的邏輯,同樣的注入方式廣泛存在於ASP .NET MVC的很多Filter邏輯中。
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public sealed class HttpPostAttribute : ActionMethodSelectorAttribute
{
// Fields
private static readonly AcceptVerbsAttribute _innerAttribute = new AcceptVerbsAttribute(HttpVerbs.Post);
// Methods
public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
{
return _innerAttribute.IsValidForRequest(controllerContext, methodInfo);
}
}
關於Attribute的詳細內容,請參考8.3節“歷史糾葛:特性和屬性”,其中的TrimAttribute特性正是應用Attribute注入進行屬性Trim過濾處理的典型應用。
本文節選自《你必須知道的.NET(第2版)》一書
圖書詳細資訊:http://space.itpub.net/13164110/viewspace-704514
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/13164110/viewspace-704622/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- PHP 控制反轉(IoC) 和 依賴注入(DI)PHP依賴注入
- PHP 控制反轉(IOC)和依賴注入(DI)PHP依賴注入
- 控制反轉與依賴注入(IOC和DI)依賴注入
- 控制反轉(IoC)與依賴注入(DI)依賴注入
- .NET IoC模式依賴反轉(DIP)、控制反轉(Ioc)、依賴注入(DI)模式依賴注入
- Java:控制反轉(IoC)與依賴注入(DI)Java依賴注入
- 深入理解控制反轉(IoC)和依賴注入(DI)依賴注入
- php實現依賴注入(DI)和控制反轉(IOC)PHP依賴注入
- 深入理解IoC(控制反轉)、DI(依賴注入)依賴注入
- 8.(轉)控制反轉(IoC)與依賴注入(DI)依賴注入
- Spring框架之IOC/DI(控制反轉/依賴注入)Spring框架依賴注入
- 理解Spring中依賴注入(DI)與控制反轉(IoC)Spring依賴注入
- OOD、DIP、IOC、DI、依賴注入容器(即 控制反轉容器,IOC Container)依賴注入AI
- 控制反轉(IOC)與依賴注入(DI)模式解析及實踐依賴注入模式
- 深入理解spring容器中的控制反轉(IOC)和依賴注入(DI)Spring依賴注入
- 淺析依賴倒轉、控制反轉、IoC 容器、依賴注入。依賴注入
- 依賴注入和控制反轉依賴注入
- Spring4學習(一)IoC控制反轉也稱為DI依賴注入Spring依賴注入
- 深入探討控制反轉(IOC)與依賴注入(DI)模式原理與應用實踐依賴注入模式
- Spring 控制反轉和依賴注入Spring依賴注入
- 什麼是控制反轉(IOC)?什麼是依賴注入?依賴注入
- Spring系列第二講 控制反轉(IoC)與依賴注入(DI),晦澀難懂麼?Spring依賴注入
- java 控制反轉和依賴注入的理解Java依賴注入
- CommunityToolkit.Mvvm8.1 IOC依賴注入控制反轉(5)UnityMVVM依賴注入
- 前端理解依賴注入(控制反轉)前端依賴注入
- spring中的控制反轉和依賴注入 --講解Spring依賴注入
- 簡單解釋什麼是 依賴注入 和 控制反轉依賴注入
- 你確定懂?徹底搞懂 控制反轉(IoC Inversion of Control )與依賴注入(DI Dependency Inversion Principle )依賴注入
- IOC容器和依賴注入依賴注入
- 依賴倒置、依賴注入和控制反轉傻傻分不清楚?依賴注入
- 反射,註解,動態代理,依賴注入控制反轉反射依賴注入
- 對控制反轉和依賴注入的突然頓悟依賴注入
- 依賴倒置(DIP)與依賴注入(DI)依賴注入
- 軟體工程入門-輕鬆理解依賴注入 (DI) 和 IoC 容器軟體工程依賴注入
- Spring理論基礎-控制反轉和依賴注入Spring依賴注入
- 控制反轉,依賴注入,依賴倒置傻傻分不清楚?依賴注入
- 詳解 Laravel 中的依賴注入和 IoCLaravel依賴注入
- 寫一個簡單的IoC容器案例,理解什麼是依賴注入和控制反轉依賴注入