Castle AOP 系列(二):对接口方法调用的拦截

Castle中有一个扩展的DynamicProxy程序集(DynamicProxy2),在这个程序集中,提供了对接口方法做动态拦截的能力。相比于对类方法的拦截,对接口方法的拦截为我们的架构设计方面提供了更大的自由度。在这里先罗列一些简单的代码,大家可以从这些代码中先思考一下接口方法的动态拦截可以应用于哪些方面,在以后的章节中,我们会深入的讨论具体的应用层面,其实这个在我们Mussel通信层的插件的实施中,于客户端产生服务端接口的Proxy起到了决定性的作用。先看代码:

接口的定义
  1. namespace Unit7   
  2. {   
  3.     public interface IPerson   
  4.     {   
  5.         void SayHello();   
  6.         void SayName(string name);   
  7.   
  8.         string GotoSchool(string schoolName, string grade, string classes);   
  9.     }   
  10. }  
方法拦截器的实现
  1. using System;   
  2. using System.Reflection;   
  3. using Castle.Core.Interceptor;   
  4.   
  5. namespace Unit7   
  6. {   
  7.     public class SimpleInterceptor : IInterceptor   
  8.     {   
  9.         public void Intercept(IInvocation invocation)   
  10.         {   
  11.             Console.WriteLine("Current MethodName:{0}", invocation.Method.Name);   
  12.   
  13.             string signature = string.Empty;   
  14.   
  15.             //在这个循环中通过反射计算出方法签名   
  16.             foreach(ParameterInfo info in invocation.Method.GetParameters())   
  17.             {   
  18.                 string paramSignature =   
  19.                     string.Format("{0} {1}",   
  20.                                   info.ParameterType.Name,   
  21.                                   info.Name);   
  22.   
  23.                 if (string.IsNullOrEmpty(signature))   
  24.                     signature = paramSignature;   
  25.                 else signature = signature + "," + paramSignature;   
  26.             }   
  27.                
  28.             //输出方法签名   
  29.             Console.WriteLine("Method Signature:{0} ({1})",   
  30.                 invocation.Method.ReturnType.Name,   
  31.                 signature);   
  32.   
  33.             //直接设置返回值为函数名称   
  34.             invocation.ReturnValue = invocation.Method.Name;   
  35.         }   
  36.     }   
  37. }  
调用的主程序
  1. using System;   
  2. using Castle.DynamicProxy;   
  3.   
  4. namespace Unit7   
  5. {   
  6.     public class Program   
  7.     {   
  8.         private static int Main()   
  9.         {   
  10.                
  11.             ProxyGenerator generator = new ProxyGenerator();   
  12.                
  13.             //采用默认的基类(Object)   
  14.             IPerson person =    
  15.                 generator.CreateInterfaceProxyWithoutTarget<IPerson>
  16.                           (new SimpleInterceptor());   
  17.                
  18.             DisplayMessage(person);   
  19.   
  20.   
  21.             ProxyGenerator proxyGenerator = new ProxyGenerator();   
  22.             ProxyGenerationOptions options = new ProxyGenerationOptions();   
  23.             //改变接口对象的基类为MarshalByRefObject   
  24.             options.BaseTypeForInterfaceProxy = typeof(MarshalByRefObject);   
  25.   
  26.             Console.WriteLine();   
  27.             Console.WriteLine("=====================================");   
  28.   
  29.             IPerson person1 =   
  30.                 (IPerson) proxyGenerator.CreateInterfaceProxyWithoutTarget(   
  31.                               typeof (IPerson),   
  32.                               null, options,   
  33.                               new SimpleInterceptor());   
  34.   
  35.             DisplayMessage(person1);   
  36.   
  37.             Console.ReadLine();   
  38.             return 0;   
  39.         }   
  40.   
  41.         private static void DisplayMessage(IPerson person)   
  42.         {   
  43.             Console.WriteLine("Current BaseType:{0}", person.GetType().BaseType);   
  44.             Console.WriteLine();   
  45.   
  46.             person.SayHello();   
  47.             Console.WriteLine();   
  48.   
  49.             person.SayName("Roger");   
  50.             Console.WriteLine();   
  51.   
  52.             Console.WriteLine(   
  53.                 "Return Value:{0}",   
  54.                 person.GotoSchool("华师附小""三年级""三班"));   
  55.         }   
  56.     }   
  57. }  

上面的程序比较容易理解,大家可以自己试试。可以看到在这里我们没有对接口作任何实现,但是我们依然可以获取到接口的实例对象。并且在上面的实例中,我们 还演示了如何改变动态生成的接口实例对象的基类,这是一个非常有用的操作,在下一个章节中,我们就会看到它实际的应用,我们看看程序输出:


欢迎大家访问我的博客主站: http://www.rogertong.cn 

点击下载源程序

原文地址:https://www.cnblogs.com/isuper/p/1239889.html