• Unity 实现 AOP


    http://www.cnblogs.com/chsword/archive/2009/04/28/unity_aop.html

    前提

    引用以下文件

    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.codeplex.com/下载

    本文中的实现类继承于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方法执行前或执行后注入其它执行过程即最后形成的结果可能是:

    image

    这里除了箭头所指的一句外其它的都是注入进去这个方法的。

    定义处理代码

    这里我们先定义一段处理方法的代码,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这时我们看到的结果就是:

    image

    代码下载:

     http://www.cnblogs.com/chsword/archive/2009/04/28/unity_aop.html

  • 相关阅读:
    c# 泛型总结
    透过字节码分析java基本类型数组的内存分配方式。
    c#索引器
    redis在asp.net 中的应用
    Unity3D shaderLab
    Unity3d Asset Store 打不开
    C# 类型转换的开销
    [转]权重算法
    Coroutine的原理以及实现
    在Unity3D里使用WinForm
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/1872723.html
Copyright © 2020-2023  润新知