原文:黃聰:Microsoft Enterprise Library 5.0 系列教程(八) Unity Dependency Injection and Interception

依賴注入容器Unity:

Unity的構造類似於Castle中的IOC(控制反轉 或者叫依賴注入)容器,我們使用抽象介面來隔離使用者和具體實現之間的依賴關係,但是不管再怎麼抽象,最終還是要建立具體實現類的例項,這種建立具體實現類的例項物件就會造成對於具體實現的依賴,為了消除這 種建立依賴性,需要把依賴移出到程式的外部(比如配置檔案)。使用依賴注入後,這些類完全是基於抽象介面編寫而成的,所以可以最大限度地適應需求的變化。 依賴注入的形式有三種,分別為構造子注入(Constructor Injection)、設值方法注入(Setter Injection)和介面注入(Interface Injection)。

還是和以前一樣,我們用實際的需求來做演示,說明這個模組到底能解決什麼實際的問題吧(以下的例子是仿照TerryLee的文章: Castle IOC容器快速入門,在此我使用Unity來恢復現場,給大家演示如何用Unity解決相同的問題 ):

現在假如我們有這樣一個需求,開發一個日誌元件,把日誌資訊輸出到文字檔案,同時對輸出的資訊進行格式化,以示意性的程式碼來實現.

1.建立一個新的控制檯應用程式,加入需要的Dll檔案,並新增需要的引用:

新增引用:

using Microsoft.Practices.Unity;

2.測試:

程式碼

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity;

namespace test
{
class Program
{
staticvoid Main(string[] args)
{
Console.WriteLine("測試一:");
test1();

Console.WriteLine("測試二:");
test2();
}

privatestaticvoid test1()
{
//1. 日誌格式化只是日誌服務中的一個元件.(注:在此例項化該元件沒有多大意義,唯一用處只是用來給服務提供一個引數)
ILogFormatter logFormatter =new TextFormatter("/");

//2.建立服務
ILog logServer =new TextFileLog(@"C:\test.log",logFormatter);

//3.使用服務
logServer.Write("日誌正文");
}

privatestaticvoid test2()
{
//1.註冊了一個容器;
IUnityContainer container =new UnityContainer();

//2.向容器中註冊ILog服務,並告訴容器用TextFileLog實現這個服務
container.RegisterType<ILog, TextFileLog>();

//3.向容器中註冊ILogFormatter,並告知容器用TextFormatter實現它
// 容器發現類的建構函式還需要另外一個引數Target,這裡用InjectionProperty注入該引數
container
.RegisterType<ILogFormatter, TextFormatter>(new InjectionProperty("Target", "/"))
.RegisterInstance<string>(@"C:\test.log");

//4.獲取服務
ILog log = container.Resolve<ILog>();

//5.使用服務,到此為止我們都沒有使用new關鍵字建立一個具體類的例項,
// 完全遮蔽了元件和服務的例項化,而由Unity自動裝配,使得程式更加的靈活.
log.Write("日誌正文");
}
}

}

執行結果:

到此為止,我們從中要了解到幾個知識點:

1.服務

服務是一個個的介面, 介面約定了服務,從而使隨意替換服務的實現對使用介面服務的程式碼沒有任何的影響。像我們上面例子中的ILog,ILogFormatter都是一個個服務,我們在這個例子中支實現了一個文字檔案的日誌記錄,如果你要是實 現資料庫記錄的日誌記錄,都必須要遵守ILog這個介面。

2.元件

簡單來說元件是一個可 重用的程式單元,它實現了某個介面,並僅僅只實現了這一個良好的介面。也就是說,元件是實現了某個服務介面的類。像上例中的TextFileLog,TextFormatter都 是元件

3.自動裝配

在上面的例子中,大家 可能都已經注意到了,TextFileLog依賴於TextFormatter, 我們卻沒有在配置檔案中指定它們之間的依賴關係,這就是Castle IOC聰明的一個地方,它能 夠自動管理元件之間的依賴關係,而無需編寫特定的xml config來配置,即自動裝配的意思。

這裡還有篇從別的網站Copy過來的IOC介紹,很形象生動,希望對大家的理解有所幫助:

Spring框架中也有IoC(Inversion of Control,控制倒轉)。並且是spring的核心,貫穿始終。所謂IoC,對於spring框架來說,就是由spring來負責控制物件的生命週期和 物件間的關係。這是什麼意思呢,舉個簡單的例子,我們是如何找女朋友的?常見的情況是,我們到處去看哪裡有長得漂亮身材又好的mm,然後打聽她們的興趣愛好、qq號、電話號、ip號、iq號………,想辦法認識她們,投其所好送其所要,然後嘿嘿……這個過程是複雜深奧的,我們必須自己設計和麵對每個環節。傳 統的程式開發也是如此,在一個物件中,如果要使用另外的物件,就必須得到它(自己new一個,或者從JNDI中查詢一個),使用完之後還要將物件銷燬(比如Connection等),物件始終會和其他的介面或類藕合起來。
  那麼IoC是如何做的呢?有點像通過婚介找女朋友,在我和女朋友之間引入了一個第三者:婚姻介紹所。婚介管理了很多男男女女的資料,我可以向婚介提出一個列表,告訴它我想找個什麼樣的女朋友,比如長得像李嘉欣,身材像林熙雷,唱歌像周杰倫,速度像卡洛斯,技術像齊達內之類的,然後婚介就會按照我們的要求,提供一個mm,我們只需要去和她談戀愛、結婚就行了。簡單明瞭,如果婚介給我們的人選不符合要求,我們就會丟擲異常。整個過程不再由我自己控制,而是有婚介這樣一個類似容器的機構來控制。Spring所倡導的開發方式就是如此,所有的類都會在spring容器中登記,告訴spring你是個什麼東西,你需要什麼東西,然後spring會在系統執行到適當的時候,把你要的東西主動給你,同時也把你交給其他需要你的東西。所有的類的建立、銷燬都由 spring來控制,也就是說控制物件生存週期的不再是引用它的物件,而是spring。對於某個具體的物件而言,以前是它控制其他物件,現在是所有物件都被spring控制,所以這叫控制反轉。

文中示例程式下載:

(> ' []' )>  點選下載  <( '[] '< )