关于微软企业库中依赖注入容器Unity两种生成对象的实现

看了很多牛人关于Unity的文章后,深有感触

 

下面简单介绍下UnityContainer 怎么注册和生成具体类的对象

 

假设我们一个命名空间为UnityContainerText的项目中拥有一个接口和实现该接口的类

 

namespace UnityContainerText
{
public interface ILogger
{
void Writer();
}
}

 

public class DatabaseLogger:ILogger
{


public void Writer()
{
Console.WriteLine(
" Hello! Unity " );
}


}

 

当然,工作开始前还要先导入Microsoft.Practices.Unity.Configuration.dllMicrosoft.Practices.Unity.dll

 

首先介绍的是硬编码的方式注册和获取类实例:如下图

 

 

关于微软企业库中依赖注入容器Unity两种生成对象的实现 代码
class Program
{
static void 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的结构图

 

 

关于微软企业库中依赖注入容器Unity两种生成对象的实现

 

 

 

关于微软企业库中依赖注入容器Unity两种生成对象的实现 代码
< configSections >
< 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 >
< type type = " 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:类型映射的目标类型。如果这是映射注册,这就是映射的目标对象的类型。此属性是可选的。

 

 

准备工作完成后开始代码实现

 

关于微软企业库中依赖注入容器Unity两种生成对象的实现 代码
static void Main ( string[] args )
{

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两种生成对象的实现

 

 

 

这就是Unity的一个简单应用。。

 

 

 

首先感谢许多牛人的帮助,我们要学的东东太多。。。大家努力吧

 

 

你可能感兴趣的:(unity)