網上關於Unity IOC容器使用的方法已很多,但未能做一個總結,故我這里總結一下,方便大家選擇。
首先講一下通過代碼來進行類型映射,很簡單,代碼如下:
unityContainer = new UnityContainer(); //實例化一個容器 unityContainer.RegisterType<IClassTest, ClassTest>(); //注冊類型映射 unityContainer.Resolve<IClassTest>();//解析並獲取類型的實例
然而實際情況,我們一般不可能直接硬編碼在程序中,因為像上述代碼上與普通的直接new一個實例並無什么區別,都會存在很明顯的依賴,若后面需要更換類,則必需修改程序源碼,那就失去了IOC的作用了,所以大多都采用外部配置文件來實現自動映射,下面是我總結的幾種配置方法(嚴格意義來講,還是一種),供大家選擇。
第一種配置如下:
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration"/>
</configSections>
<unity>
<typeAliases>
<typeAlias alias="IRepository`1" type="ConsoleApplication1.DDD.Interface.IRepository`1,ConsoleApplication1" />
<typeAlias alias="Post" type="ConsoleApplication1.Entities.Post,ConsoleApplication1" />
<typeAlias alias="Category" type="ConsoleApplication1.Entities.Category,ConsoleApplication1" />
<typeAlias alias="Author" type="ConsoleApplication1.Entities.Author,ConsoleApplication1" />
<typeAlias alias="IClassTest" type="ConsoleApplication1.DDD.Interface.IClassTest,ConsoleApplication1" />
</typeAliases>
<container>
<types>
<type type="IRepository[Post]" mapTo="ConsoleApplication1.DDD.Infrastructure.Repositories.PostRepository,ConsoleApplication1" />
<type type="IRepository[Category]" mapTo="ConsoleApplication1.DDD.Infrastructure.Repositories.CategoryRepository,ConsoleApplication1" />
<type type="IRepository[Author]" mapTo="ConsoleApplication1.DDD.Infrastructure.Repositories.AuthorRepository,ConsoleApplication1" />
<type type="IClassTest" mapTo="ConsoleApplication1.DDD.Interface.ClassTest,ConsoleApplication1" />
</types>
</container>
</unity>
注意配置中的[]方括號表示的是泛型參數,typeAliases->typeAlias中的type及types->type中的mapTo均需配置類型的完整限定名以及類型所在的程序集,中間以逗號分隔,比如:ConsoleApplication1.DDD.Interface.IRepository`1 表示一個IRepository<T>泛型類型,而ConsoleApplication1表示這個泛型所在的程序集,並不是命名空間哦!
第二種配置如下:
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration"/>
</configSections>
<unity>
<aliases>
<add alias="IRepository`1" type="ConsoleApplication1.DDD.Interface.IRepository`1,ConsoleApplication1" />
<add alias="Post" type="ConsoleApplication1.Entities.Post,ConsoleApplication1" />
<add alias="Category" type="ConsoleApplication1.Entities.Category,ConsoleApplication1" />
<add alias="Author" type="ConsoleApplication1.Entities.Author,ConsoleApplication1" />
<add alias="IClassTest" type="ConsoleApplication1.DDD.Interface.IClassTest,ConsoleApplication1" />
</aliases>
<container>
<register type="IRepository[Post]" mapTo="ConsoleApplication1.DDD.Infrastructure.Repositories.PostRepository,ConsoleApplication1" />
<register type="IRepository[Category]" mapTo="ConsoleApplication1.DDD.Infrastructure.Repositories.CategoryRepository,ConsoleApplication1" />
<register type="IRepository[Author]" mapTo="ConsoleApplication1.DDD.Infrastructure.Repositories.AuthorRepository,ConsoleApplication1" />
<register type="IClassTest" mapTo="ConsoleApplication1.DDD.Interface.ClassTest,ConsoleApplication1" ></register>
</container>
</unity>
第三種配置如下(其實是上面兩種的簡寫形式):
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration"/>
</configSections>
<unity>
<assembly name="ConsoleApplication1"></assembly>
<namespace name="ConsoleApplication1.Entities"></namespace>
<namespace name="ConsoleApplication1.DDD.Interface"></namespace>
<namespace name="ConsoleApplication1.DDD.Infrastructure.Repositories"></namespace>
<container>
<register type="IRepository[Post]" mapTo="PostRepository" />
<register type="IRepository[Category]" mapTo="CategoryRepository" />
<register type="IRepository[Author]" mapTo="AuthorRepository" />
<register type="IClassTest" mapTo="ClassTest" ></register>
</container>
</unity>
代碼中使用方法:
unityContainer = new UnityContainer();
unityContainer.LoadConfiguration();//如果配置中指定了容器節點的名字name,則需要指定名字
unityContainer.Resolve<IRepository<Post>>();//解析並實例化一個對象
//以下是采用獨立的配置文件(如:unity.config)的使用方法:
IUnityContainer container = new UnityContainer();
string configFile = "Unity.config";
var fileMap = new ExeConfigurationFileMap { ExeConfigFilename = configFile };
//從config文件中讀取配置信息
Configuration configuration =ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
//獲取指定名稱的配置節
UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
//載入名稱為FirstClass 的container節點
container.LoadConfiguration(section, "MyContainer");
從配置的內容來講,一看就知道是第三種配置比較的高效與簡潔,其實現原理也很簡單,就是將需要映射的相關類型的程序集及所在命名空間先全部定義在unity節點中,然后就可以直接配置注冊映射,當然上面的配置都很簡單,沒有包含其它一些屬性,比如配置lifetime、constructor等,這些需依據實際情況來配置,在此不作說明,可參考網上其它牛人的教程。
