Unity是微軟Patterns & Practices團隊所開發的一個輕量級的,而且可擴展的依賴注入(Dependency Injection)容器,它支持經常使用的三種依賴注入方式:構造器注入(Constructor Injection)、屬性注入(Property Injection),以及方法調用注入(Method Call Injection).mysql
假設咱們有下面的場景代碼,在代碼裏面有一個很簡單的customer對象,customer 對象有個save 方法, 這個方法經過調用ICustomerDataAccess.Save將數據持久到數據庫中, 在列子中咱們實現了dataaccess的sql版本和mysql版本,也就是說咱們這個customer對象,能夠支持持久化到sql server 或 mysql.sql
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.Practices.Unity; namespace UnitySample { public interface ICustomerDataAccess { void Save(Customer c); } public class CustomerSqlDataAccess : ICustomerDataAccess { public void Save(Customer c) { Console.Write("{2}, save data id:{0},name{1}",c.Id,c.Name,this.GetType().ToString()); } } public class CustomerMysqlDataAccess : ICustomerDataAccess { public void Save(Customer c) { Console.Write("{2}, save data id:{0},name{1}", c.Id, c.Name, this.GetType().ToString()); } } public class Customer { public ICustomerDataAccess CustomerDataAccess { get; set; } public string Id { get; set; } public string Name { get; set; } public void Save() { CustomerDataAccess.Save(this); } } class Program { static void Main(string[] args) { } } }
傳統作法多是在配置文件中填幾個一個變量 dbType = sql or my sql. 而後在customer 對象中根據設定的db type 來實力化不一樣的dataaccess.數據庫
代碼可能會是下面這個樣子,這樣的話,customer 對象實際上依賴於CustomerSqlDataAccess 和 CustomerSqlDataAccess 的,並且,將來好比要新增長其餘數據庫的支持,則必須修改customer 對象的源代碼。函數
public Customer()
{
if (DbType = "sql") { CustomerDataAccess = new CustomerSqlDataAccess(); } else { CustomerDataAccess = new CustomerSqlDataAccess(); } }
下面咱們使用unity 來解除customer 對象對 CustomerSqlDataAccess 和 CustomerSqlDataAccess 的依賴。this
1. 配置unityspa
爲了之後調用方便,我這裏創建了一個靜態方法,而後注入了兩個dataaccess。code
public class UnitySetup { public static void Config() { var container = new UnityContainer(); container.RegisterType<ICustomerDataAccess, CustomerSqlDataAccess>(); container.RegisterType<ICustomerDataAccess, CustomerSqlDataAccess>("mysql"); } }
而後咱們須要在Main函數中調用這個方法配置unity containter.server
static void Main(string[] args) { UnitySetup.Config(); }
2. 標記屬性注入對象
這步很簡單,直接在customer 類中的ICustomerDataAccess 定義上面添加[Dependency]標註便可。blog
[Dependency] public ICustomerDataAccess CustomerDataAccess { get; set; }
3. 經過resove 獲取對象
var container = new UnityContainer(); UnitySetup.Config(container); var sqlCustomer = container.Resolve<ICustomerDataAccess>(); var mysqlCustomer = container.Resolve<ICustomerDataAccess>("mysql");
上面的代碼就分別獲取了CustomerSqlDataAccess 實例和CustomerSqlDataAccess實例
1. 配置unity
unityContainer.RegisterType<Customer>( new InjectionConstructor(new ResolvedParameter<ICustomerDataAccess>())); unityContainer.RegisterType<Customer>("mysqlCustomer", new InjectionConstructor(new ResolvedParameter<ICustomerDataAccess>("mysql")));
添加兩行註冊customer 對想到container.
2. 獲取
var sqlCustomer = container.Resolve<Customer>(); var myqlCustomer = container.Resolve<Customer>("mysqlCustomer");
完整代碼以下
using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.Practices.Unity; namespace UnitySample { public interface ICustomerDataAccess { void Save(Customer c); } public class CustomerSqlDataAccess : ICustomerDataAccess { public void Save(Customer c) { Console.WriteLine("{2}, save data id:{0},name{1}",c.Id,c.Name,this.GetType().ToString()); } } public class CustomerMysqlDataAccess : ICustomerDataAccess { public void Save(Customer c) { Console.WriteLine("{2}, save data id:{0},name{1}", c.Id, c.Name, this.GetType().ToString()); } } public class UnitySetup { public static void Config(IUnityContainer unityContainer) { unityContainer.RegisterType<ICustomerDataAccess, CustomerSqlDataAccess>(); unityContainer.RegisterType<ICustomerDataAccess, CustomerMysqlDataAccess>("mysql"); unityContainer.RegisterType<Customer>( new InjectionConstructor(new ResolvedParameter<ICustomerDataAccess>())); unityContainer.RegisterType<Customer>("mysqlCustomer", new InjectionConstructor(new ResolvedParameter<ICustomerDataAccess>("mysql"))); } } public class Customer { private ICustomerDataAccess CustomerDataAccess { get; set;} public string Id { get; set; } public string Name { get; set; } public Customer(ICustomerDataAccess customerDataAccess) { CustomerDataAccess = customerDataAccess; } public void Save() { CustomerDataAccess.Save(this); } } class Program { static void Main(string[] args) { var container = new UnityContainer(); UnitySetup.Config(container); var sqlCustomer = container.Resolve<Customer>(); var myqlCustomer = container.Resolve<Customer>("mysqlCustomer"); sqlCustomer.Save(); myqlCustomer.Save(); Console.ReadKey(); } } }
方法調用注入和輸入注入有點相似,只須要在調用的方法上面添加[InjectionMethod] 標註便可
1. 配置unity
unityContainer.RegisterType<Customer>("mysqlCustomer", new InjectionMethod("SetDataAccess", new ResolvedParameter<ICustomerDataAccess>("mysql")));
2. 獲取
var sqlCustomer = container.Resolve<Customer>(); var myqlCustomer = container.Resolve<Customer>("mysqlCustomer");
完成後的代碼以下
using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.Practices.Unity; namespace UnitySample { public interface ICustomerDataAccess { void Save(Customer c); } public class CustomerSqlDataAccess : ICustomerDataAccess { public void Save(Customer c) { Console.WriteLine("{2}, save data id:{0},name{1}",c.Id,c.Name,this.GetType().ToString()); } } public class CustomerMysqlDataAccess : ICustomerDataAccess { public void Save(Customer c) { Console.WriteLine("{2}, save data id:{0},name{1}", c.Id, c.Name, this.GetType().ToString()); } } public class UnitySetup { public static void Config(IUnityContainer unityContainer) { unityContainer.RegisterType<ICustomerDataAccess, CustomerSqlDataAccess>(); unityContainer.RegisterType<ICustomerDataAccess, CustomerMysqlDataAccess>("mysql"); unityContainer.RegisterType<Customer>("mysqlCustomer", new InjectionMethod("SetDataAccess", new ResolvedParameter<ICustomerDataAccess>("mysql"))); } } public class Customer { private ICustomerDataAccess CustomerDataAccess { get; set;} public string Id { get; set; } public string Name { get; set; } public void Save() { CustomerDataAccess.Save(this); } [InjectionMethod] public void SetDataAccess(ICustomerDataAccess dataAccess) { CustomerDataAccess = dataAccess; } } class Program { static void Main(string[] args) { var container = new UnityContainer(); UnitySetup.Config(container); var sqlCustomer = container.Resolve<Customer>(); var mysqlCustomer = container.Resolve<Customer>("mysqlCustomer"); sqlCustomer.Save(); mysqlCustomer.Save(); Console.ReadKey(); } } }
好了,經過使用unity 依賴注入,customer 對象再也不依賴具體的CustomerSqlDataAccess 和 CustomerMysqlDataAccess., 只依賴於接口ICustomerDataAccess。
上面就是unity 的基本用法介紹。