依賴注入容器Unity Application Block快速入門
概述
Unity是微軟模式與實踐團隊開發的一個輕量級、可擴展的依賴注入容器,之前我也有過一篇文章《Enterprise Library 4.0中的依賴注入容器(Unity)預覽》對其做過介紹。微軟模式與時間團隊已經在2月份發布了Unity February 2008 CTP版本,官方主頁是:http://www.codeplex.com/unity,大家可以到網站上去下載相關的源代碼。本文將通過一些示例讓您對Unity使用有一個逐步的認識和了解。
準備相關代碼
為了接下來的說明,我們先編寫幾個后面需要的接口和類:
接口ILogger
public interface ILogger { void Write(string message); }
FlatFileLogger類
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中創建容器實例有兩種方法,一是直接使用構造函數創建,如下代碼所示:
class Program { static void Main(string[] args) { IUnityContainer container = new UnityContainer(); } }
第二種通過父容器創建容器,在Unity中提供了層級容器的創建,即可以通過父容器來逐級創建容器:
圖1 Unity中層級容器
通過父容器來創建容器可以使用CreateChildContainer:
class Program { static void Main(string[] args) { UnityContainer parentContainer = new UnityContainer(); UnityContainer childContainer = parentContainer.CreateChildContainer(); } }
采用層級容器的好處是我們可以對于有不同生命周期的對象放在不同的容器中,如果一個子容器被釋放,不會影響到其它子容器中的對象,但是如果根節點處父容器釋放后,所有的子容器都將被釋放。
class Program { static void Main(string[] args) { UnityContainer parentContainer = new UnityContainer(); UnityContainer childContainer = parentContainer.CreateChildContainer(); // can use both generated objects here // Dispose child container childContainer.Dispose(); // can use only object in parent container here // Dispose parent container parentContainer.Dispose(); } }
注冊接口映射
在Unity中提供了Register方法供我們在容器中注冊接口映射:
class Program { static void Main(string[] args) { IUnityContainer container = new UnityContainer(); container.Register<ILogger, DatabaseLogger>(); container.Register<ILogger, FlatFileLogger>("flatfileLogger"); } }
第一個泛型參數是基類型,第二個泛型參數是組件類型,它們之間必須滿足一定的泛型約束關系:
IUnityContainer Register<TFrom, TTo>() where TTo : TFrom;
另外,如果在注冊組件時沒有指定我們也可以使用非泛型的Register方法進行接口映射:
class Program { static void Main(string[] args) { IUnityContainer container = new UnityContainer();
container.Register(typeof(ILogger),typeof(DatabaseLogger)); container.Register(typeof(ILogger),typeof(FlatFileLogger),"flatfileLogger"); } }
獲取對象實例
在Unity中提供了Get方法用以獲取對象實例,如下代碼所示:
class Program { static void Main(string[] args) { IUnityContainer container = new UnityContainer(); container.Register<ILogger, FlatFileLogger>(); ILogger logger = container.Get<ILogger>(); logger.Write("TerryLee"); } }
在上面代碼中,我們在容器中注冊了一個ILogger接口到FlatFileLogger的映射,當調用Get<ILogger>()方法時,將返回ILogger的一個默認的類型實例。運行代碼可以看到:
在之前注冊接口映射部分,Register方法有一個重載是為接口映射指定一個特定的名稱,這樣我們可以根據名稱和接口來獲取一個特定類型的對象實例,如下面的代碼我們同時注冊FlatFileLogger和DatabaseLogger到接口ILogger的映射,并未DatabaseLogger指定一個名稱,在使用Get方法的時候就可以通過ILogger和指定的名稱來獲取DatabaseLogger實例:
class Program { static void Main(string[] args) { IUnityContainer container = new UnityContainer(); container.Register<ILogger, FlatFileLogger>(); container.Register<ILogger, DatabaseLogger>("databaseLogger"); ILogger logger = container.Get<ILogger>("databaseLogger"); logger.Write("TerryLee"); } }
再運行代碼,可以看到獲取到了DatabaseLogger實例:
如果我們同時同時注冊FlatFileLogger和DatabaseLogger到接口ILogger的映射,并且不指定任何名稱,那么直接調用Get方法將會返回后注冊的組件的對象實例,如下面的代碼:
class Program { static void Main(string[] args) { IUnityContainer container = new UnityContainer(); container.Register<ILogger, FlatFileLogger>(); container.Register<ILogger, DatabaseLogger>(); ILogger logger = container.Get<ILogger>(); logger.Write("TerryLee"); } }
運行后會返回DatabaseLogger實例:
當然我們也可以使用非泛型的Get方法來獲取對象實例:
class Program { static void Main(string[] args) { IUnityContainer container = new UnityContainer(); container.Register<ILogger, FlatFileLogger>(); ILogger logger = container.Get(typeof(ILogger)) as ILogger; logger.Write("TerryLee"); } }
獲取所有對象實例
除了可以獲取單個對象實例之外,我們還可以一次獲取容器中所有與某一接口映射的所有對象實例,但是需要依賴于在注冊映射時提供的名稱,如果沒有指定名稱,通過GetAll方法不會被獲取到。
class Program { static void Main(string[] args) { IUnityContainer container = new UnityContainer(); container.Register<ILogger, FlatFileLogger>(); container.Register<ILogger, FlatFileLogger>("flatFileLogger"); container.Register<ILogger, DatabaseLogger>("DatabaseLogger");
IEnumerable<ILogger> loggers = container.GetAll<ILogger>(); foreach (ILogger logger in loggers) { if (null != logger) { Console.WriteLine(logger.GetType().ToString()); } } } }運行后如下,第一個沒有提供名稱的類型實例不會被獲取到:
結束語
關于Unity的一個簡單使用就到這里了,希望能夠對大家有用。使用Unity簡單來說分為創建容器、注冊接口映射、獲取對象實例這樣三步,在下篇文章中,將會說到如何使用配置文件注冊接口映射以及如何注冊Singleton實例等內容。
Worktile,新一代簡單好用、體驗極致的團隊協同、項目管理工具,讓你和你的團隊隨時隨地一起工作。完全免費,現在就去了解一下吧。
https://worktile.com

Unity是微軟模式與實踐團隊開發的一個輕量級、可擴展的依賴注入容器,之前我也有過一篇文章《Enterprise Library 4.0中的依賴注入容器(Unity)預覽》對其做過介紹。微軟模式與時間團隊已經在2月份發布了Unity February 2008 CTP版本,官方主頁是:http://www.codeplex.com/unity,大家可以到網站上去下載相關的源代碼。本文將通過一些示例讓您對Unity使用有一個逐步的認識和了解。
概述
準備相關代碼
創建容器
注冊接口映射
獲取對象實例
……
浙公網安備 33010602011771號