zoukankan      html  css  js  c++  java
  • 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 

    点击下载源程序

  • 相关阅读:
    容器源码分析之——ArrayList
    JVM详解(四)--运行时数据区:程序计数器(PC 寄存器)
    JVM详解(三)-- 运行时数据区:概述和线程
    JVM详解(二)-- 第2章 类加载器子系统
    vue组件传入样式参数
    vue重定向父路径无法向子路径传递参数
    cpp引用内部的元素指针变化问题
    无法获取vuex中对象的属性
    前端笔记收藏
    vue组件传参
  • 原文地址:https://www.cnblogs.com/isuper/p/1239889.html
Copyright © 2011-2022 走看看