關于微軟企業庫中依賴注入容器Unity兩種生成對象的實現
看了很多牛人關于Unity的文章后,深有感觸
下面簡單介紹下UnityContainer 怎么注冊和生成具體類的對象
假設我們一個命名空間為UnityContainerText的項目中擁有一個接口和實現該接口的類
{
publicinterface ILogger
{
void Writer();
}
}
{
publicvoid Writer()
{
Console.WriteLine("Hello! Unity");
}
}
當然,工作開始前還要先導入Microsoft.Practices.Unity.Configuration.dll和Microsoft.Practices.Unity.dll
首先介紹的是硬編碼的方式注冊和獲取類實例:如下圖
代碼
{
staticvoid Main(string[] args)
{
IUnityContainer container =new UnityContainer();
container.RegisterType<ILogger, DatabaseLogger>() ;
ILogger logger = container.Resolve<ILogger>();
logger.Writer();
Console.ReadLine();
}
}
首先創建UnItyContainer對象container,并且通過container.RegisterType<接口,實現接口的類>()方法
實現了從ILogger到DatabaseLogger的映射,從而使用container.Resolve<ILogger>()或者container.Resolve(typeof(ILogger))
的方法取得了DatabaseLogger類的對象
聰明的你可能立馬看到了這種硬編碼方式的不足,就是不斷的添加,導致產生高耦合的情況
利用WEBCONFIG配置文件可以解決上述問題
在說配置文件前,先讓大家看下UnIty在webconfig的結構圖

代碼
<section name="unity"type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<sectionGroup name="system.web.extensions"type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<sectionGroup name="scripting"type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="scriptResourceHandler"type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
<sectionGroup name="webServices"type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="jsonSerialization"type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/>
<section name="profileService"type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
<section name="authenticationService"type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
<section name="roleService"type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
</sectionGroup>
</sectionGroup>
</sectionGroup>
</configSections>
<appSettings/>
<connectionStrings/>
<unity>
<typeAliases>
<typeAliase alias="IFileLogger"type="UnityContainerText.ILogger,UnityContainerText">
</typeAliase>
</typeAliases>
<containers>
<container>
<types>
<typetype="UnityContainerText.ILogger,UnityContainerText" mapTo="UnityContainerText.DatabaseLogger"></type>
</types>
</container>
</containers>
</unity>
如上圖:
Unity的配置都在Unity節點下
typeAliases是配置類型別名的,在typeAliases中配置的類型可以直接在contaniners使用,當在containers中使用時
就不需要填寫完整的類型了,只需填在typeAliases注冊的別名就可以了。當然也可以直接在container中注冊完整的類型。
typeAlias 中alias是別名稱,type 是類型。
containners節點中可以包含多個container,同時一個container中可以嵌套多個container了。
name:在注冊此類型時使用的名稱。此屬性是可選的,如果不指定此屬性,所在的 add 元素即為默認的類型映射。
type:容器中配置的源類型。如果這是映射注冊,這就是映射的起始對象的類型;如果這是單件注冊,這就是對象的類型。此屬性是必須的。
mapTo:類型映射的目標類型。如果這是映射注冊,這就是映射的目標對象的類型。此屬性是可選的。
準備工作完成后開始代碼實現
代碼
{
IUnityContainer container = new UnityContainer();
UnityConfigurationSection section = ConfigurationManager.GetSection("unity") as UnityConfigurationSection;
section.Containers.Default.Configure(container);
ILogger logger = container.Resolve<ILogger>("databaseLogger");
logger.Writer();
Console.ReadLine();
}
第二行中的 UnityConfigurationSection section = ConfigurationManager.GetSection("unity") as UnityConfigurationSection;
這個是通過配置文件中<configSections>標簽內的<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
獲得<unity>標簽下的內容
第三行: section.Containers.Default.Configure(container);這樣就會根據配置文件的配置,向容器中注冊類型的映射;
如果配置中有多個容器,如果只是想加載某個的話,可以指定加載:section.Containers["ctrOne"].Configure(container);
隨后 ILogger logger = container.Resolve<ILogger>("databaseLogger");
便可以直接加載出對象了,而不需要先加載一堆諸如container.register().....的方法了,這樣大大降低了代碼的耦合
補充下:unity 容器可以實現子容器,也就是當父容器釋放的時候,子容器也釋放,但是子容器釋放不影響父容器的使用
UnityContainer container = parentContainer.CreateChildContainer();
如圖所示

這就是Unity的一個簡單應用。。
首先感謝許多牛人的幫助,我們要學的東東太多。。。大家努力吧

浙公網安備 33010602011771號