IOC、DI<4> Unity、AOP、MVCAOP、UnityAOP 区别
IOC():控制反转,把程序上层对下层的依赖,转移到第三方的容器来装配
是程序设计的目标,实现方式包含了依赖注入和依赖查找(.net里面只有依赖注入)
DI:依赖注入,是IOC的实习方式。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unity;
using ZEN.Interface;
using ZEN.Service;namespace UnityIOC
{class Program{static void Main(string[] args){//定义一个IOC容器IUnityContainer container = new UnityContainer();//添加映射关系container.RegisterType<ICar, TeslaCar>();//获取服务var car = container.Resolve<ICar>();car.GetName();car.GetPrice();car.GetMaxSpeed();Console.ReadKey();}}
}
一个接口多个实现进行注册
如: 接口 IPhone
实现华为手机 继承 IPhone
实现苹果手机 继承 IPhone
IUnityContainer container = new UnityContainer();//1、定义一个空容器
container.RegisterType<IPhone, HuaweiPhone>(“huawei”);//2、注册类型,表示遇到IDbInterface的类型,创建DbMSSQL的实例
container.RegisterType<IPhone, ApplePhone>(“apple”);//表示遇到IDbInterface的类型,创建DbMSSQL的实例
var huawei= container.Resolve(“huawei”);
var apple= container.Resolve(“apple”);
Console.WriteLine(huawei.xxx());
Console.WriteLine(apple.xxx());
以上还是依赖细节,完全脱离细节,需要用配置文件,跟autofac一样
这样每次生成,才会把配置文件生成到bin目录下
会发现,如果改成使用配置文件的方式实现的话,代码里面就不会依赖于细节了,只要一个接口类型。既然没有细节了,那么对项目进行如下的改造:把引用里面对细节的引用都去掉(ZEN.Service),然后Debug文件夹里面没有这个DLL了,但是这时需要把这个DLL复制到Debug目录下面,否则程序运行的时候会找不到具体实现的类型。这样就意味着程序架构只依赖于接口。
<?xml version="1.0" encoding="utf-8" ?>
<configuration><configSections><section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Unity.Configuration" /></configSections><unity><typeAliases><typeAlias alias="IPhone" type="ZEN.Interface.IPhone,ZEN.Interface"></typeAlias ><typeAlias alias="IWork" type="ZEN.Interface.IWork,ZEN.Interface"></typeAlias ><typeAlias alias="IPower" type="ZEN.Interface.IPower,ZEN.Interface"></typeAlias ><typeAlias alias="ICar" type="ZEN.Interface.ICar,ZEN.Interface"></typeAlias ><typeAlias alias="Phone" type="ZEN.Service.Phone,ZEN.Service"></typeAlias ><typeAlias alias="Work" type="ZEN.Service.Work,ZEN.Service"></typeAlias ><typeAlias alias="Power" type="ZEN.Service.Power,ZEN.Service"></typeAlias ><typeAlias alias="Car" type="ZEN.Service.TeslaCar,ZEN.Service"></typeAlias ></typeAliases><sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Unity.Interception.Configuration" /><containers><container name="testContainer"><register type="IPhone" mapTo="Phone" /><register type="IPower" mapTo="Power" /><register type="ICar" mapTo="Car" name="tesla" ><property name="work" dependencyType="IWork" /><property name="phone" dependencyType="IPhone" /></register><register type="IWork" mapTo="Work" /> </container></containers></unity>
</configuration>
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unity;using ZEN.Interface;
using System.Configuration;
using Microsoft.Practices.Unity.Configuration;
using Unity.Interception;
using Unity.Interception.Interceptors.InstanceInterceptors.InterfaceInterception;
using Microsoft.Practices.Unity;namespace UnityIOC
{class Program{static void Main(string[] args){//{ //定义一个IOC容器// IUnityContainer container = new UnityContainer();// //添加映射关系 // container.RegisterType<ICar, TeslaCar>("tesla");// container.RegisterType<ICar, XiaoMICar>("xiaomi");// container.RegisterType<IWork, Work>();// container.RegisterType<IPower, Power>();// container.RegisterType<IPhone, Phone>();// //获取服务// var car = container.Resolve<ICar>("tesla");// car.GetName();// car.GetPrice();// car.GetMaxSpeed();//}{//ExeConfigurationFileMap 要引入 System.Configuration;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);IUnityContainer container = new UnityContainer();section.Configure(container, "testContainer");var car = container.Resolve<ICar>("tesla");car.GetName();car.GetPrice();car.GetMaxSpeed();//}Console.ReadKey();}}
}
构造函数注入、属性注入、方法注入 配置文件
<?xml version="1.0" encoding="utf-8" ?>
<configuration><configSections><section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Unity.Configuration" /></configSections><unity><typeAliases><typeAlias alias="IPhone" type="ZEN.Interface.IPhone,ZEN.Interface"></typeAlias ><typeAlias alias="IWork" type="ZEN.Interface.IWork,ZEN.Interface"></typeAlias ><typeAlias alias="IPower" type="ZEN.Interface.IPower,ZEN.Interface"></typeAlias ><typeAlias alias="ICar" type="ZEN.Interface.ICar,ZEN.Interface"></typeAlias ><typeAlias alias="Phone" type="ZEN.Service.Phone,ZEN.Service"></typeAlias ><typeAlias alias="Work" type="ZEN.Service.Work,ZEN.Service"></typeAlias ><typeAlias alias="Power" type="ZEN.Service.Power,ZEN.Service"></typeAlias ><typeAlias alias="Car" type="ZEN.Service.TeslaCar,ZEN.Service"></typeAlias ></typeAliases><sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Unity.Interception.Configuration" /><containers><container name="testContainer"><register type="IPhone" mapTo="Phone" /><register type="IPower" mapTo="Power" /><register type="ICar" mapTo="Car" name="tesla" ><property name="work" dependencyType="IWork" /><property name="phone" dependencyType="IPhone" /><method name="InitIphone"><param name="_power" type="IPower" /><param name="val" type="int" value="33"/></method></register><register type="IWork" mapTo="Work" /> </container></containers></unity>
</configuration>
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);IUnityContainer container = new UnityContainer();section.Configure(container, "testContainer");var car = container.Resolve<ICar>("tesla");car.GetName();car.GetPrice();car.GetMaxSpeed();
unity IOC 源码
Unity AOP
<?xml version="1.0" encoding="utf-8" ?>
<configuration><configSections><section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Unity.Configuration" /></configSections><unity><typeAliases><typeAlias alias="IPhone" type="ZEN.Interface.IPhone,ZEN.Interface"></typeAlias ><typeAlias alias="IWork" type="ZEN.Interface.IWork,ZEN.Interface"></typeAlias ><typeAlias alias="IPower" type="ZEN.Interface.IPower,ZEN.Interface"></typeAlias ><typeAlias alias="ICar" type="ZEN.Interface.ICar,ZEN.Interface"></typeAlias ><typeAlias alias="Phone" type="ZEN.Service.Phone,ZEN.Service"></typeAlias ><typeAlias alias="Work" type="ZEN.Service.Work,ZEN.Service"></typeAlias ><typeAlias alias="Power" type="ZEN.Service.Power,ZEN.Service"></typeAlias ><typeAlias alias="Car" type="ZEN.Service.TeslaCar,ZEN.Service"></typeAlias ></typeAliases><sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Unity.Interception.Configuration" /><containers><container name="testContainer"><!AOP 需要添加这个节点 <extension type="Interception"/>/>--><extension type="Interception"/><register type="IPhone" mapTo="Phone" /><register type="IPower" mapTo="Power" /><register type="ICar" mapTo="Car" name="tesla" ><property name="work" dependencyType="IWork" /><property name="phone" dependencyType="IPhone" /><method name="InitIphone"><param name="_power" type="IPower" /><param name="val" type="int" value="33"/></method><interceptor type="InterfaceInterceptor"/><interceptionBehavior type="IOC.Common.IOC_AOP.AOP, IOC.Common"/></register><register type="IWork" mapTo="Work" /> </container></containers></unity>
</configuration>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unity.Interception.InterceptionBehaviors;
using Unity.Interception.PolicyInjection.Pipeline;namespace IOC.Common.IOC_AOP
{/// <summary>/// 不需要特性/// </summary>public class AOP : IInterceptionBehavior{public bool WillExecute{get { return true; }}public IEnumerable<Type> GetRequiredInterfaces(){return Type.EmptyTypes;}public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext){Console.WriteLine("IOC-AOP触发");return getNext().Invoke(input, getNext);}}
}
MVC中的Filter过滤器也起到AOP功能,但与unity的AOP
有所不同
mvc中的过滤器是针对action的,action前,action后
unity框架的AOP 可以针对 方法
Filter可以在action前 后 异常都扩展逻辑 AOP—针对action完整方法
Unity容器的AOP也是需要的, AOP—针对方法里面的业务层扩展的