1. 依赖倒置原则和IOC
2. IOC(Inversion of Control)的好处
3. 介绍和使用Unity
依赖倒置原则(DIP):上层和下层之间,依赖抽象,而不依赖细节
IOC 控制反转,把上端对下端细节的依赖,转移给第三方,上端只依赖抽象
Unity:就是一个第三方的容器
public static void Show() { { Console.WriteLine("**************************普通用法*************************"); IPhone phone = new AndroidPhone(); phone.Call(); Console.WriteLine(" phone.Headphone==null? {0}", phone.Headphone == null); Console.WriteLine("phone.Microphone==null? {0}", phone.Microphone == null); Console.WriteLine(" phone.Power==null? {0}", phone.Power == null); } { Console.WriteLine("*********************Iunity用法,无注入*******************"); IUnityContainer container = new UnityContainer(); container.RegisterType<IPhone, AndroidPhone>(); container.RegisterType<IMicrophone, Microphone>(); container.RegisterType<IHeadphone, Headphone>(); container.RegisterType<IPower, Power>(); IPhone phone = container.Resolve<IPhone>(); phone.Call(); Console.WriteLine(" phone.Headphone==null? {0}", phone.Headphone == null); Console.WriteLine("phone.Microphone==null? {0}", phone.Microphone == null); Console.WriteLine(" phone.Power==null? {0}", phone.Power == null); } { Console.WriteLine("*********************Iunity用法,注入*******************"); IUnityContainer container = new UnityContainer(); container.RegisterType<IPhone, ApplePhone>(); container.RegisterType<IMicrophone , Microphone >(); container.RegisterType<IHeadphone , Headphone>(); container.RegisterType<IPower, Power>(); IPhone phone = container.Resolve<IPhone>(); phone.Call(); Console.WriteLine(" phone.Headphone==null? {0}", phone.Headphone == null); Console.WriteLine("phone.Microphone==null? {0}", phone.Microphone == null); Console.WriteLine(" phone.Power==null? {0}", phone.Power == null); //IOC还可以做: 单例 单线程单例 AOP } }
三种注入方式
/// <summary> /// 依赖注入三种方式:构造函数注入 属性注入 方法注入 /// </summary> public class ApplePhone : IPhone { [Dependency] //属性注入 public IMicrophone Microphone { get; set; } public IHeadphone Headphone { get; set; } public IPower Power { get; set; } public ApplePhone() { Console.WriteLine("{0}构造函数", this.GetType().Name); } [InjectionConstructor ]//构造函数注入,可以不要特性,默认使用参数最多的构造函数 public ApplePhone (IHeadphone iHeadphone) { this.Headphone = iHeadphone; Console.WriteLine("{0}带参数构造函数", this.GetType().Name); } public void Call() { Console.WriteLine("{0}打电话", this.GetType().Name); } [InjectionMethod ]//方法注入:必须是public public void Init(IPower power) { this.Power = power; Console.WriteLine("初始化函数{0}", this.GetType().Name); } }
写配置文件
<configuration> <configSections> <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/> </configSections> <unity> <containers> <container name="testContainer"> <register type="IOCUnity.IPhone,IOCUnity" mapTo="IOCUnity.ApplePhone, IOCUnity"/> <register type="IOCUnity.IMicrophone, IOCUnity" mapTo="IOCUnity.Microphone, IOCUnity"/> <register type="IOCUnity.IHeadphone, IOCUnity" mapTo="IOCUnity.Headphone, IOCUnity"/> <register type="IOCUnity.IPower, IOCUnity" mapTo="IOCUnity.Power, IOCUnity"/> <register type="IOCUnity.IPhone,IOCUnity" mapTo="IOCUnity.AndroidPhone, IOCUnity" name="android"/> <register type="IOCUnity.IPhone,IOCUnity" mapTo="IOCUnity.ApplePhone, IOCUnity" name="apple"/> </container> </containers> </unity> </configuration>
Unity的标准运用方式
public class UnityConfig { public static void Show() { IUnityContainer container = new UnityContainer();//准备容器 ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap(); fileMap.ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "CfgFiles\Unity.Config.xml");//找配置文件的路径 Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None); UnityConfigurationSection section = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName); section.Configure(container, "testContainer");//注册 IPhone phone = container.Resolve<IPhone>(); //new AndroidPhone();//创建对象 phone.Call(); Console.WriteLine("****************************************"); IPhone phone2 = container.Resolve<IPhone>("apple"); //new AndroidPhone();//创建对象 phone2.Call(); Console.WriteLine("****************************************"); IPhone phone3 = container.Resolve<IPhone>("android"); //new AndroidPhone();//创建对象 phone3.Call(); }