Unity.InterceptionExtension.ICallHandler实现一个操作日志记录功能
其它跟上一次一样
<?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"><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><policyInjection></policyInjection><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.PolicyInjection.Pipeline;namespace IOC.Common.IOC_AOP
{class SimpleCallHandler : ICallHandler{public int Order {get;set;}public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext){Console.WriteLine(input.Target.GetType().Name);return getNext()(input, getNext);}}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unity;
using Unity.Interception.PolicyInjection.Pipeline;
using Unity.Interception.PolicyInjection.Policies;namespace IOC.Common.IOC_AOP
{public class SimpleCallHandlerAttribute : HandlerAttribute{ public override ICallHandler CreateHandler(IUnityContainer container){return new SimpleCallHandler() { Order=this.Order};}}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using IOC.Common.IOC_AOP;
namespace ZEN.Interface
{public interface ICar{[SimpleCallHandler]void GetName();void GetPrice();void GetMaxSpeed();}
}
对IUnityContainer 进行封装
走指定构造函数
就不需要加特性啦
这样既可完成对象注册的同时对构造函数参数进行注入,此时还有另外一个需求,就是虽然在注册的时候已经对构造函数参数进行了初始化
在Unity中,已经帮我们解决了这个问题,我们可以通过ParameterOverride和ParameterOverrides来实现,其中ParameterOverride是针对一个参数,而ParameterOverrides是针对参数列表,有关注册参数初始化及参数重载的全部代码如下:
1、在使用ParameterOverride方法来重载参数时,如果注册的参数是一个具体的对象就需要使用OnType这个扩展方法来指定对应的类型,否则会报错。
2、在使用ParameterOverrides进行重载参数时,可以使用如上面代码的方式进行指定,但是同样需要使用OnType来指定,不过这个的OnType指定的类型是注册的对象类型。
注册类型同时初始化构造函数参数并重载调用
》》如果初始化是三个参数的构造函数, Resolve解析,是2个参数,只会替换对应的两个参数。
》》集合初始化器 赋值
》》配置文件
using System;
using System.Collections.Generic;
using System.Linq;
using Unity;
using System.Configuration;
using System.IO;
using Microsoft.Practices.Unity.Configuration;
using Unity.Resolution;namespace IOC.Common.IOC_AOP
{public class ZenUnityContainerHelper{private IUnityContainer container;public IUnityContainer Container {private set {container = value;}get {return Container;}}public ZenUnityContainerHelper(){this.container = new UnityContainer() ;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); section.Configure(container, "testContainer");}public T GetServer<T>(){return container.Resolve<T>();}/// <summary>/// /// </summary>/// <typeparam name="T"></typeparam>/// <param name="configName">配置文件中指定的name,对于同一个接口,多个实现情况</param>/// <returns></returns>public T GetServer<T>(string configName){return container.Resolve<T>(configName);}/// <summary>/// 返回构结函数带参数/// </summary>/// <typeparam name="T">依赖对象</typeparam>/// <param name="parameterList">参数集合(参数名,参数值)</param>/// <returns></returns>public T GetServer<T,M>(Dictionary<string, object> parameterList){var list = new ParameterOverrides();foreach (KeyValuePair<string, object> item in parameterList){list.Add(item.Key, item.Value);}return container.Resolve<T>(list.OnType<M>());}/// <summary>/// 返回构结函数带参数/// </summary>/// <typeparam name="T">依赖对象</typeparam>/// <param name="ConfigName">配置文件中指定的文字(没写会报异常)</param>/// <param name="parameterList">参数集合(参数名,参数值)</param>/// <returns></returns>public T GetServer<T,M>(string configName, Dictionary<string, object> parameterList){var list = new ParameterOverrides();foreach (KeyValuePair<string, object> item in parameterList){list.Add(item.Key, item.Value);}return container.Resolve<T>(configName,list.OnType<M>());}}
}
》》》 使用封装
ZenUnityContainerHelper zenContainer= new ZenUnityContainerHelper();var tesla_car = zenContainer.GetServer<ICar>("tesla");tesla_car.GetName(); var xiaomi_car = zenContainer.GetServer<ICar>("xiaomi" );xiaomi_car.GetName();Dictionary<string, object> parm = new Dictionary<string, object>();parm.Add("age", "一百");parm.Add("policy", "遥遥领先");var xiaomi_car1 = zenContainer.GetServer<ICar,XiaoMICar>("xiaomi2", parm);xiaomi_car1.GetName();Console.WriteLine("-----------------------------------");
配置文件
<?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 ><typeAlias alias="xiaomi" type="ZEN.Service.XiaoMICar,ZEN.Service"></typeAlias ></typeAliases><sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Unity.Interception.Configuration" /><containers><container name="testContainer"><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><policyInjection></policyInjection><interceptor type="InterfaceInterceptor"/><!--<interceptionBehavior type="IOC.Common.IOC_AOP.AOP, IOC.Common"/>--></register><register type="ICar" mapTo="xiaomi" name="xiaomi" ><property name="work" dependencyType="IWork" /><property name="phone" dependencyType="IPhone" /><method name="InitIphone"><param name="_power" type="IPower" /></method><policyInjection></policyInjection><interceptor type="InterfaceInterceptor"/><!--<interceptionBehavior type="IOC.Common.IOC_AOP.AOP, IOC.Common"/>--></register><register type="ICar" mapTo="xiaomi" name="xiaomi2" ><property name="work" dependencyType="IWork" /><property name="phone" dependencyType="IPhone" /><method name="InitIphone"><param name="_power" type="IPower" /></method><constructor><param name="age" type="System.String" /><param name="policy" type="System.String" ></param></constructor><policyInjection></policyInjection><interceptor type="InterfaceInterceptor"/><!--<interceptionBehavior type="IOC.Common.IOC_AOP.AOP, IOC.Common"/>--></register><register type="IWork" mapTo="Work" /> </container></containers></unity>
</configuration>
注册类型同时初始化属性并重载调用
public static void ResolveProperty()
{//注册对象关系时初始化对象的属性container.RegisterType<IXXX, XXX>(new InjectionProperty("Policy", "AA"),new InjectionProperty("Desc", "描述"));Console.WriteLine("-----------默认调用输出-------------");Console.WriteLine(container.Resolve<IXXX().Policy);Console.WriteLine(container.Resolve<IXXX>().Desc);Console.WriteLine("-----------重载后调用输出-------------");//以下2种写法效果是一样的,同上面的构造函数参数重载//var myXXX = container.Resolve<IXXX>(new PropertyOverride("Policy", "重载后"),// new PropertyOverride("Desc", "重载后的描述"));var myXXX = container.Resolve<IXXX>(new PropertyOverrides(){{"Policy","重载后的"},{"Desc","重载后的描述"}}.OnType<MyClass>());Console.WriteLine(myXXX.Policy);Console.WriteLine(myXXX.Desc);
}