前提 引用以下文件 Microsoft.Practices.ObjectBuilder2.dll Microsoft.Practices.Unity.dll Microsoft.Practices.Unity.Configuration.dll Microsoft.Practices.Unity.Interception.dll Microsoft.Practices.Unity.Interception.Configuration.dll Microsoft.Practices.Unity.StaticFactory.dll 可以从网站http://unity./下载 本文中的实现类继承于IOutput接口 1: public interface IOutput { 2: void Output(int x); 3: } 实现效果 我有两个方法可以输出字符串, 调用IOutput的实现类来输出的,如: 1: class OutputImplement2 : IOutput { 2: public void Output(int x) { 3: Console.WriteLine("output:{0}", x); 4: } 5: } 调用它即在Main函数中 1: var op2=new OutputImplement2(); 2: op2.Output(22); 即可,而AOP的作用是通过其它代码,向op2.Output方法执行前或执行后注入其它执行过程即最后形成的结果可能是: 这里除了箭头所指的一句外其它的都是注入进去这个方法的。
定义处理代码 这里我们先定义一段处理方法的代码,Unity规定它是ICallHandler的一个实现 1: public class MyHandler : ICallHandler { 2: public int Order { get; set; }//这是ICallHandler的成员,表示执行顺序 3: public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext) { 4: Console.WriteLine("方法名: {0}", input.MethodBase.Name); 5: Console.WriteLine("参数:"); 6: for (var i = 0; i < input.Arguments.Count; i++) { 7: Console.WriteLine("{0}: {1}", input.Arguments.ParameterName(i), input.Arguments[i]); 8: } 9: Console.WriteLine("执行"); 10: //这之前插入方法执行前的处理 11: var retvalue = getNext()(input, getNext);//在这里执行方法 12: //这之后插入方法执行后的处理 13: Console.WriteLine("完成"); 14: return retvalue; 15: } 16: } 好,下面我们来看看怎么把MyHandler与IOutput关联起来,大体有2种方法 1.通过代码直接关联 这种实现方式比较“硬”。 它是利用Atrribute来实现这种关联的,首先,先建一个Attribute。 1: public class MyHandlerAttribute : HandlerAttribute { 2: public override ICallHandler CreateHandler(IUnityContainer container) { 3: return new MyHandler();//返回MyHandler 4: } 5: } 然后在IOutput的实现中使用如下代码: 1: [MyHandler] 2: class OutputImplement1 : IOutput { 3: public void Output(int x) { 4: Console.WriteLine("重典执行此方法输出:{0}", x); 5: } 6: } 这里靠此Attribute就将二者关联了起来 现在执行处写: 1: var container1 = new UnityContainer() 2: .AddNewExtension<Interception>() 3: .RegisterType<IOutput, OutputImplement1>();//声明UnityContainer并注册IOutput 4: container1 5: .Configure<Interception>() 6: .SetInterceptorFor<IOutput>(new InterfaceInterceptor()); 7: var op1 = container1.Resolve<IOutput>(); 8: op1.Output(11);//调用 That’s all OK. 2.用配置文件处理 如果用配置文件的话就不用Attribute了,所以实现的类如下 1: class OutputImplement2 : IOutput { 2: public void Output(int x) { 3: Console.WriteLine("重典执行此方法输出:{0}", x); 4: } 5: } 这里不使用属性来标记了,而使用配置文件,我们建一个名为Unity.xml的配置文件(配置文件长,可以后看): 1: <?xml version="1.0" encoding="utf-8" ?> 2: <configuration> 3: <configSections> 4: <section name="unity" 5: type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, 6: Microsoft.Practices.Unity.Configuration, Version=1.2.0.0, 7: Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> 8: </configSections> 9: <unity> 10: <typeAliases> 11: <typeAlias alias="singleton" 12: type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager, Microsoft.Practices.Unity" /> 13: <typeAlias alias="transparentProxy" 14: type="Microsoft.Practices.Unity.InterceptionExtension.TransparentProxyInterceptor, Microsoft.Practices.Unity.Interception" /> 15: <typeAlias alias="typeMatchingRule" 16: type="Microsoft.Practices.Unity.InterceptionExtension.TypeMatchingRule, Microsoft.Practices.Unity.Interception"/> 17: <typeAlias alias="interception" 18: type="Microsoft.Practices.Unity.InterceptionExtension.Interception, Microsoft.Practices.Unity.Interception"/> 19: <typeAlias alias="IOutput" type="ConsoleApplication1.IOutput, ConsoleApplication1" /> 20: <typeAlias alias="MyHandler" type="ConsoleApplication1.MyHandler, ConsoleApplication1" /> 21: <typeAlias alias="OutputImplement2" type="ConsoleApplication1.OutputImplement2, ConsoleApplication1" /> 22: </typeAliases> 23: <containers> 24: <container name="DefContainer"> 25: <types> 26: <type type="IOutput" mapTo="OutputImplement2" name=""> 27: <lifetime type="singleton" /> 28: </type> 29: </types> 30: </container> 31: </containers> 32: </unity> 33: </configuration> 最后我们来执行,要比第一种方法复杂一点: 1: var container2 = new UnityContainer().AddNewExtension<Interception>();//声明UnityContainer 2: var map = new ExeConfigurationFileMap {ExeConfigFilename = "Unity.xml"};//使用此配置文件 3: var config 4: = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None); 5: var section 6: = (UnityConfigurationSection)config.GetSection("unity");//读取配置文件节点 7: section.Containers["DefContainer"].Configure(container2); 8: container2.Configure<Interception>() 9: .SetDefaultInterceptorFor<IOutput>(new TransparentProxyInterceptor()) 10: .AddPolicy("LogMethod") 11: .AddMatchingRule(new TypeMatchingRule("IOutput")) 12: .AddCallHandler(typeof(MyHandler)); 13: var op2 = container2.Resolve<IOutput>(); 14: op2.Output(22);//调用
OK这时我们看到的结果就是: |
|