IoC之Unity
一、什麽是IcC?
IoC(Inversion of Control,控制反轉)又稱“依賴註入”(Dependence Injection,DI)。
控制反轉就是創建對象的權利由開發人員控制,轉為由容器來控制。
依賴註入就是通過容器創建對象的,是通過在構造方法的參數,屬性設置和接口等方式註入的。
IoC的基本概念是:不創建對象,但是描述創建它們的方式。在代碼中不直接與對象和服務連接,但在配置文件(或程序)中描述創建關系,容器負責將它們聯系起來。
二、什麽是Unity?
Unity是微軟開發的一款輕量級、可擴展的IoC框架,可通過代碼或者XML配置文件的形式類配置對象和對象直接的關系。
在運行時直接調用容器即可獲得我們需要的對象,以便建立松耦合的程序。
三、創建Unity Demo
1.新建控制臺項目UnityDemo
2.右鍵UnityDemo項目,選擇“管理NuGet程序包”,安裝Unity程序包
3.新建幾個接口IPhone,IHeadphone,IMicrophone,IPower
public interface IHeadphone { } public interface IMicrophone { } public interfaceIPower { } public interface IPhone { /// <summary> /// 打電話 /// </summary> void Call(); IMicrophone iMicrophone { get; set; } IHeadphone iHeadphone { get; set; } IPower iPower { get; set; } }
4.新建繼承接口的類
public class Headphone:IHeadphone { } public class Microphone: IMicrophone { } public class Power:IPower { } public class AndroidPhone : IPhone { public IHeadphone iHeadphone { get; set; } public IMicrophone iMicrophone { get; set; } public IPower iPower { get; set; } public AndroidPhone() { Console.WriteLine("{0}構造函數", this.GetType().Name); } public void Call() { Console.WriteLine("{0}打電話", this.GetType().Name); } } public class ApplePhone : IPhone { [Dependency] //屬性註入 public IHeadphone iHeadphone { get; set; } public IMicrophone iMicrophone { get; set; } public IPower iPower { get; set; } public ApplePhone() { Console.WriteLine("{0}構造函數", this.GetType().Name); } [InjectionConstructor] //構造函數註入 public ApplePhone(IMicrophone iMicrophone) { this.iMicrophone = iMicrophone; Console.WriteLine("{0}帶參數構造函數", this.GetType().Name); } public void Call() { Console.WriteLine("{0}打電話", this.GetType().Name); } [InjectionMethod] //屬性註入 public void Init(IPower iPower) { this.iPower = iPower; } }
四、編程方式註冊對應關系
Unity有三種註入方式:1.屬性註入,使用[Dependency]特性 2.構造方法註入,使用[InjectionConstructor]特性(沒有此特性,默認使用參數最多的構造方法) 3.方法註入,使用[InjectionMethod]特性
1.創建一個UnityContainer對象
2.通過UnityContainer對象的RegisterType方法來註冊對象和對象之間的關系
3.通過UnityContainer對象的Resolve方法來獲取指定對象關聯的對象
static void Main(string[] args) { try { Console.WriteLine("********************AndroidPhone**********************"); { IUnityContainer container = new UnityContainer(); container.RegisterType<IPhone, AndroidPhone>(); container.RegisterType<IHeadphone, Headphone>(); container.RegisterType<IMicrophone, Microphone>(); container.RegisterType<IPower, Power>(); IPhone phone = container.Resolve<IPhone>(); phone.Call(); //未註入 iHeadphone,iMicrophone,iPower 對象都為空 Console.WriteLine("phone.iHeadphone == null? {0}", phone.iHeadphone == null); Console.WriteLine("phone.iMicrophone == null? {0}", phone.iMicrophone == null); Console.WriteLine("phone.iPower == null? {0}", phone.iPower == null); } Console.WriteLine("********************ApplePhone**********************"); { IUnityContainer container = new UnityContainer(); container.RegisterType<IPhone, ApplePhone>(); container.RegisterType<IHeadphone, Headphone>(); container.RegisterType<IMicrophone, Microphone>(); container.RegisterType<IPower, Power>(); IPhone phone = container.Resolve<IPhone>(); phone.Call(); //通過屬性註入,構造函數註入,方法註入 iHeadphone,iMicrophone,iPower 對象不為空 Console.WriteLine("phone.iHeadphone == null? {0}", phone.iHeadphone == null); Console.WriteLine("phone.iMicrophone == null? {0}", phone.iMicrophone == null); Console.WriteLine("phone.iPower == null? {0}", phone.iPower == null); } } catch (Exception ex) { Console.WriteLine(ex.Message); } Console.ReadKey(); }
運行結果:
五、通過配置文件配置對應關系
項目結構:
配置文件:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" /> </configSections> <unity> <!--定義別名--> <aliases> <add alias="IPhone" type="UnityDemo.Interface.IPhone,UnityDemo" /> <add alias="IHeadphone" type="UnityDemo.Interface.IHeadphone,UnityDemo" /> <add alias="IMicrophone" type="UnityDemo.Interface.IMicrophone,UnityDemo" /> <add alias="IPower" type="UnityDemo.Interface.IPower,UnityDemo" /> <add alias="AndroidPhone" type="UnityDemo.Service.AndroidPhone,UnityDemo" /> <add alias="ApplePhone" type="UnityDemo.Service.ApplePhone,UnityDemo" /> <add alias="Headphone" type="UnityDemo.Service.Headphone,UnityDemo" /> <add alias="Microphone" type="UnityDemo.Service.Microphone,UnityDemo" /> <add alias="Power" type="UnityDemo.Service.Power,UnityDemo" /> </aliases> <!--容器--> <container name="MyContainer"> <!--映射關系--> <register type="IPhone" mapTo="ApplePhone"/> <register type="IHeadphone" mapTo="Headphone"/> <register type="IMicrophone" mapTo="Microphone"/> <register type="IPower" mapTo="Power"/> </container> </unity> </configuration>
調用代碼:
public static void ContainerConfiguration() { IUnityContainer container = new UnityContainer(); ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap { ExeConfigFilename ="Unity.config"}; Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None); UnityConfigurationSection section =(UnityConfigurationSection)configuration.GetSection("unity"); container.LoadConfiguration(section, "MyContainer"); IPhone phone = container.Resolve<IPhone>(); phone.Call(); //通過屬性註入,構造函數註入,方法註入 iHeadphone,iMicrophone,iPower 對象不為空 Console.WriteLine("phone.iHeadphone == null? {0}", phone.iHeadphone == null); Console.WriteLine("phone.iMicrophone == null? {0}", phone.iMicrophone == null); Console.WriteLine("phone.iPower == null? {0}", phone.iPower == null); }
IoC之Unity