一.介绍
控制反转(Inversion of Control,简称IoC):整洁架构思想,不允许内部获知外部的存在,这就导致了我们必须在内层定义与外层交互的接口,通过依赖注入的方式将外层实现注入到内部来。
依赖注入(Dependency Injection,简称DI): 高层通过接口隔离具体实现的依赖,就意味着具体实现转移到了外部,究竟使用哪一个具体实现,由外部调用者来决定,只有在运行调用者代码时才将外面的依赖传递给高层。
依赖倒置原则(Dependency Inversion Principle,DIP) : 高层模块不应该依赖于底层模块,两者应该依赖于抽象。本质:我们要依赖不变或稳定的元素(类,模块或层),抽象不应该依赖细节,细节应该与抽象。
二.Unity使用介绍
使用Nuget包安装以下组件:
Unity : 5.8.6
Unity.Interception : 5.5.3
<!--Unity 配置文件--> <configuration> <configSections> <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Unity.Configuration"/> </configSections> <unity> <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Unity.Interception.Configuration"/> <containers> <container name="testContainer"> <register type="Interface.IPhone,Interface" mapTo="Services.AndroidPhone, Services" /> <register type="Interface.IPhone,Interface" mapTo="Services.TestPhone, Services" name="TestPhone"/> </container> </containers> </unity> </configuration>
<!--Unity 配置文件讲解--> <unity> <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Unity.Interception.Configuration"/> <containers> <container name="容器名称"> <register type="接口的命名空间(namespace).接口名,接口的命名空间" mapTo="实现类的命名空间.实现类名, 实现类的命名空间" /> <register type="Interface.IPhone,Interface" mapTo="Services.TestPhone, Services" name="TestPhone"/> </container> </containers> </unity> </configuration>
封装UnityIocHelper调用类:
using System; using System.Configuration; using System.IO; using Microsoft.Practices.Unity.Configuration; using Unity; using Unity.Resolution; namespace MyIOC.Untiy { /// <summary> /// 描 述:UnityIoc /// </summary> public class UnityIocHelper { #region 构造方法 /// <summary> /// 构造方法 /// </summary> /// <param name="containerName">容器名称</param> private UnityIocHelper(string containerName) { ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap(); fileMap.ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "CfgFiles\Unity.Config");//找配置文件的路径 Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None); UnityConfigurationSection section = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName); //UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity"); // <unity configSource="Configioc.config" /> if (section.Containers.Count > 0) { _container = new UnityContainer(); section.Configure(_container, containerName); } } #endregion #region 属性 /// <summary> /// 容器 /// </summary> private readonly IUnityContainer _container; /// <summary> /// 容器实例 /// </summary> private static readonly UnityIocHelper instance = new UnityIocHelper("testContainer"); /// <summary> /// UnityIoc容器实例 /// </summary> public static UnityIocHelper Instance { get { return instance; } } #endregion #region 获取对应接口的具体实现类 /// <summary> /// 获取实现类(默认映射) /// </summary> /// <typeparam name="T">接口类型</typeparam> /// <returns>接口</returns> public T GetService<T>() { return _container.Resolve<T>(); } /// <summary> /// 获取实现类(默认映射)带参数的 /// </summary> /// <typeparam name="T">接口类型</typeparam> /// <param name="parameter">参数</param> /// <returns>接口</returns> public T GetService<T>(params ParameterOverride[] parameter) { return _container.Resolve<T>(parameter); } /// <summary> /// 获取实现类(指定映射)带参数的 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="name"></param> /// <param name="parameter"></param> /// <returns>接口</returns> public T GetService<T>(string name, params ParameterOverride[] parameter) { return _container.Resolve<T>(name, parameter); } #endregion #region 判断接口是否被注册了 /// <summary> /// 判断接口是否被实现了 /// </summary> /// <typeparam name="T">接口类型</typeparam> /// <returns>bool</returns> public bool IsResolve<T>() { return _container.IsRegistered<T>(); } /// <summary> /// 判断接口是否被实现了 /// </summary> /// <typeparam name="T">接口类型</typeparam> /// <param name="name">映射名称</param> /// <returns></returns> public bool IsResolve<T>(string name) { return _container.IsRegistered<T>(name); } #endregion } }
调用示例:
var android = UnityIocHelper.Instance.GetService<IPhone>();//不带参数,默认取容器的没用name的,但只能有一个,不然会异常. android.Call();//AndroidPhone
var android = UnityIocHelper.Instance.GetService<IPhone>("TestPhone"); //取容器内名称匹配的.
android.Call();//TestPhone
三.Unity实现AOP
<!--Unity 配置文件--> <container name="ContainerAOP"> <extension type="Interception"/> <register type="Interface.IPhone,Interface" mapTo="Services.AndroidPhone, Services"> <interceptor type="InterfaceInterceptor"/> <interceptionBehavior type="AOP.LogAfterBehavior,AOP"/> <interceptionBehavior type="AOP.LogBeforeBehavior,AOP"/> </register> </container>
调用示例:
var androidAOP = UnityIocHelper.AOPInstance.GetService<IPhone>();//跟普通调用一样. androidAOP.Call();
四.Unity实现单例
<container name="testContainer"> <register type="Interface.IPhone,Interface" mapTo="Services.AndroidPhone, Services" > <lifetime type="singleton" /> </register> </container>
五.源码下载: