使用MicrosoftPracticesUnity 依赖注入.docx
《使用MicrosoftPracticesUnity 依赖注入.docx》由会员分享,可在线阅读,更多相关《使用MicrosoftPracticesUnity 依赖注入.docx(10页珍藏版)》请在冰豆网上搜索。
使用MicrosoftPracticesUnity依赖注入
使用Microsoft.Practices.Unity依赖注入
Unity是微软Patterns&Practices团队所开发的一个轻量级的,并且可扩展的依赖注入(DependencyInjection)容器,它支持常用的三种依赖注入方式:
构造器注入(ConstructorInjection)、属性注入(PropertyInjection),以及方法调用注入(MethodCallInjection).
假设我们有下面的场景代码,在代码里面有一个很简单的customer对象,customer对象有个save方法,这个方法通过调用ICustomerDataAccess.Save将数据持久到数据库中,在列子中我们实现了dataaccess的sql版本和mysql版本,也就是说我们这个customer对象,可以支持持久化到sqlserver或mysql.
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
usingMicrosoft.Practices.Unity;
namespaceUnitySample
{
publicinterfaceICustomerDataAccess
{
voidSave(Customerc);
}
publicclassCustomerSqlDataAccess:
ICustomerDataAccess
{
publicvoidSave(Customerc)
{
Console.Write("{2},savedataid:
{0},name{1}",c.Id,c.Name,this.GetType().ToString());
}
}
publicclassCustomerMysqlDataAccess:
ICustomerDataAccess
{
publicvoidSave(Customerc)
{
Console.Write("{2},savedataid:
{0},name{1}",c.Id,c.Name,this.GetType().ToString());
}
}
publicclassCustomer
{
publicICustomerDataAccessCustomerDataAccess{get;set;}
publicstringId{get;set;}
publicstringName{get;set;}
publicvoidSave()
{
CustomerDataAccess.Save(this);
}
}
classProgram
{
staticvoidMain(string[]args)
{
}
}
}
传统做法可能是在配置文件中填几个一个变量dbType=sqlormysql.然后在customer对象中根据设定的dbtype来实力化不同的dataaccess.
代码可能会是下面这个样子,这样的话,customer对象实际上依赖于CustomerSqlDataAccess和CustomerSqlDataAccess的,而且,未来比如要新增加其他数据库的支持,则必须修改customer对象的源代码。
publicCustomer()
{
if(DbType="sql")
{
CustomerDataAccess=newCustomerSqlDataAccess();
}
else
{
CustomerDataAccess=newCustomerSqlDataAccess();
}
}
下面我们使用unity来解除customer对象对CustomerSqlDataAccess和CustomerSqlDataAccess的依赖。
一、属性注入(PropertyInjection)
1.配置unity
为了以后调用方便,我这里建立了一个静态方法,然后注入了两个dataaccess。
publicclassUnitySetup
{
publicstaticvoidConfig()
{
varcontainer=newUnityContainer();
container.RegisterType<ICustomerDataAccess,CustomerSqlDataAccess>();
container.RegisterType<ICustomerDataAccess,CustomerSqlDataAccess>("mysql");
}
}
然后我们需要在Main函数中调用这个方法配置unitycontainter.
staticvoidMain(string[]args)
{
UnitySetup.Config();
}
2.标记属性注入
这步很简单,直接在customer类中的ICustomerDataAccess定义上面添加[Dependency]标注即可。
[Dependency]
publicICustomerDataAccessCustomerDataAccess{get;set;}
3.通过resove获取对象
varcontainer=newUnityContainer();
UnitySetup.Config(container);
varsqlCustomer=container.Resolve<ICustomerDataAccess>();
varmysqlCustomer=container.Resolve<ICustomerDataAccess>("mysql");
上面的代码就分别获取了CustomerSqlDataAccess实例和CustomerSqlDataAccess实例
二、构造器注入(ConstructorInjection)
1.配置unity
unityContainer.RegisterType<Customer>(
newInjectionConstructor(newResolvedParameter<ICustomerDataAccess>()));
unityContainer.RegisterType<Customer>("mysqlCustomer",
newInjectionConstructor(newResolvedParameter<ICustomerDataAccess>("mysql")));
添加两行注册customer对想到container.
2.获取
varsqlCustomer=container.Resolve<Customer>();
varmyqlCustomer=container.Resolve<Customer>("mysqlCustomer");完整代码如下
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Data;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
usingMicrosoft.Practices.Unity;
namespaceUnitySample
{
publicinterfaceICustomerDataAccess
{
voidSave(Customerc);
}
publicclassCustomerSqlDataAccess:
ICustomerDataAccess
{
publicvoidSave(Customerc)
{
Console.WriteLine("{2},savedataid:
{0},name{1}",c.Id,c.Name,this.GetType().ToString());
}
}
publicclassCustomerMysqlDataAccess:
ICustomerDataAccess
{
publicvoidSave(Customerc)
{
Console.WriteLine("{2},savedataid:
{0},name{1}",c.Id,c.Name,this.GetType().ToString());
}
}
publicclassUnitySetup
{
publicstaticvoidConfig(IUnityContainerunityContainer)
{
unityContainer.RegisterType<ICustomerDataAccess,CustomerSqlDataAccess>();
unityContainer.RegisterType<ICustomerDataAccess,CustomerMysqlDataAccess>("mysql");
unityContainer.RegisterType<Customer>(
newInjectionConstructor(newResolvedParameter<ICustomerDataAccess>()));
unityContainer.RegisterType<Customer>("mysqlCustomer",
newInjectionConstructor(newResolvedParameter<ICustomerDataAccess>("mysql")));
}
}
publicclassCustomer
{
privateICustomerDataAccessCustomerDataAccess{get;set;}
publicstringId{get;set;}
publicstringName{get;set;}
publicCustomer(ICustomerDataAccesscustomerDataAccess)
{
CustomerDataAccess=customerDataAccess;
}
publicvoidSave()
{
CustomerDataAccess.Save(this);
}
}
classProgram
{
staticvoidMain(string[]args)
{
varcontainer=newUnityContainer();
UnitySetup.Config(container);
varsqlCustomer=container.Resolve<Customer>();
varmyqlCustomer=container.Resolve<Customer>("mysqlCustomer");
sqlCustomer.Save();
myqlCustomer.Save();
Console.ReadKey();
}
}
}
三、方法调用注入(MethodCallInjection)
方法调用注入和输入注入有点类似,只需要在调用的方法上面添加[InjectionMethod]标注即可
1.配置unity
unityContainer.RegisterType<Customer>("mysqlCustomer",
newInjectionMethod("SetDataAccess",newResolvedParameter<ICustomerDataAccess>("mysql")));
2.获取
varsqlCustomer=container.Resolve<Customer>();
varmyqlCustomer=container.Resolve<Customer>("mysqlCustomer");
完成后的代码如下
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Data;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
usingMicrosoft.Practices.Unity;
namespaceUnitySample
{
publicinterfaceICustomerDataAccess
{
voidSave(Customerc);
}
publicclassCustomerSqlDataAccess:
ICustomerDataAccess
{
publicvoidSave(Customerc)
{
Console.WriteLine("{2},savedataid:
{0},name{1}",c.Id,c.Name,this.GetType().ToString());
}
}
publicclassCustomerMysqlDataAccess:
ICustomerDataAccess
{
publicvoidSave(Customerc)
{
Console.WriteLine("{2},savedataid:
{0},name{1}",c.Id,c.Name,this.GetType().ToString());
}
}
publicclassUnitySetup
{
publicstaticvoidConfig(IUnityContainerunityContainer)
{
unityContainer.RegisterType<ICustomerDataAccess,CustomerSqlDataAccess>();
unityContainer.RegisterType<ICustomerDataAccess,CustomerMysqlDataAccess>("mysql");
unityContainer.RegisterType<Customer>("mysqlCustomer",
newInjectionMethod("SetDataAccess",newResolvedParameter<ICustomerDataAccess>("mysql")));
}
}
publicclassCustomer
{
privateICustomerDataAccessCustomerDataAccess{get;set;}
publicstringId{get;set;}
publicstringName{get;set;}
publicvoidSave()
{
CustomerDataAccess.Save(this);
}
[InjectionMethod]
publicvoidSetDataAccess(ICustomerDataAccessdataAccess)
{
CustomerDataAccess=dataAccess;
}
}
classProgram
{
staticvoidMain(string[]args)
{
varcontainer=newUnityContainer();
UnitySetup.Config(container);
varsqlCustomer=container.Resolve<Customer>();
varmysqlCustomer=container.Resolve<Customer>("mysqlCustomer");
sqlCustomer.Save();
mysqlCustomer.Save();
Console.ReadKey();
}
}
}
好了,通过使用unity依赖注入,customer对象不再依赖具体的CustomerSqlDataAccess和CustomerMysqlDataAccess.,只依赖于接口ICustomerDataAccess。
上面就是unity的基本用法介绍。