之前Terry Lee 已經介紹過Unity的簡單使用了,不過那篇文章是針對舊版本的,現在的版本1.2版略有不同。
我下載了Unity並做了一個簡單的測試,項目的分布是這個樣子:
LoggerTest.Interface.ILogger 主要是介面, 一個簡單的不能再簡單的方法結構:
public interface ILogger{ void Write(string message);}
LoggerTest 是實現這個介面的project, 恩,跟Terry Lee 的例子一樣,實現兩個就OK了,分別是FlatFileLogger和DatabaseLogger。
namespace LoggerTest{ public class FlatFileLogger : ILogger { public void Write(string message) { Console.WriteLine(String.Format("Message:{0}", message)); Console.WriteLine("Target:FlatFile"); } } public class DatabaseLogger : ILogger { public void Write(string message) { Console.WriteLine(String.Format("Message:{0}", message)); Console.WriteLine("Target:Database"); } }}
下面是Unity出場的時候了,可能初學者不知道要引用哪些組件(像我就是),這裡截個圖告訴大家:
如果是顯示注入,調用Microsoft.Practices.Unity 和Microsoft.Practices.ObjectBuilder2 就可以了;如果是通過設定檔注入,那麼就要另外引用Microsoft.Practices.Unity.Configuration
好了,那麼基本上就大功告成,代碼裡已經注釋的很清楚了
//顯式擷取UnityContainer private IUnityContainer GetContainer_Directly() { IUnityContainer container = new UnityContainer(); //如果註冊多個類型需要指定名字(名字是任意的) //否則當調用ResolveAll<>()時,那些沒有指定名字的將會擷取不到 //但是,Resolve<>() 會預設取那些空名字的注入對象。 container.RegisterType<ILogger, DatabaseLogger>("databaseLogger"); container.RegisterType<ILogger, FlatFileLogger>("flatfileLogger"); return container; } //從設定檔擷取UnityContainer private IUnityContainer GetContainer_Config() { IUnityContainer container = new UnityContainer(); UnityConfigurationSection section = (UnityConfigurationSection)System.Configuration.ConfigurationManager.GetSection("unity"); section.Containers[0].Configure(container); return container; } public void Test() { IUnityContainer container = GetContainer_Config(); foreach (ILogger logger in container.ResolveAll<ILogger>()) logger.Write("Bruce Lee"); }
設定檔:
<?xml version="1.0" encoding="utf-8" ?><configuration> <configSections> <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" /> </configSections> <unity> <containers> <container name="One"> <types> <type type="LoggerTest.Interface.ILogger, LoggerTest.Interface" name="FlatFileLogger" mapTo="LoggerTest.FlatFileLogger, LoggerTest"/> <type type="LoggerTest.Interface.ILogger, LoggerTest.Interface" name="DatabaseLogger" mapTo="LoggerTest.DatabaseLogger, LoggerTest"/> </types> </container> </containers> </unity></configuration>
運行效果:
後記:Unity的簡單介紹
以下摘自貪睡蟲: http://www.cnblogs.com/liujian969/archive/2009/01/17/1377446.html
描述
Unity 應用程式塊(Unity)是一個輕量級、可擴充的依賴注入容器,支援建構函式、屬性和方法調用注入。它為開發人員提供了如下好處:
- 簡化了對象的建立,尤其是分層的對象結構和依賴。
- 允許開發人員在運行時或者配置中指定依賴的需求抽象,以及簡化了橫切關注點的管理。
- 服務定位功能允許客戶代碼儲存或者緩衝容器。這在開發人員可以持久化容器到 ASP.NET Session 或者 Application 中的 ASP.NET Web 應用程式中特別有用。
常見情境
除了單獨解決橫切關注點如日誌、認證、授權、緩衝和異常處理的組件以外,現代業務系統通常由定製的業務對象和在應用程式中完成特殊的或者一般的任務的組件組成。
成功構建這樣的應用程式的關鍵是獲得解耦的或者極度松耦合的設計。松耦合的應用程式更加靈活、更加易於維護。同時在開發期間進行測試,可以類比對象的樁(輕量級類比的實現),這增強了實質的依賴。例如,資料庫連接、網路連接、ERP 串連和富使用者介面組件。
依賴注入是一種用於構建松耦合應用程式的主要技術。它提供了處理對象間依賴的方法。例如,一個處理使用者資訊的對象可能依賴於訪問資料存放區、驗證資訊和檢查使用者是否被授權執行更新的其他對象。依賴注入技術可以確保使用者類正確的初始化及組裝所有這些對象,特別是依賴是抽象的地方。
使用容器可以有很多好處,但它會改變應用程式的設計方式,尤其適合於基於組件的開發,朋友們可以有選擇的使用它。