码迷,mamicode.com
首页 > 其他好文 > 详细

Castle

时间:2016-08-07 08:30:40      阅读:223      评论:0      收藏:0      [点我收藏+]

标签:

 

Castle AOP 系列(一):对类方法调用的拦截(有源码)

标签: aopAOPCastle对类方法调用的拦截
技术分享 分类:
 

目录(?)[+]

 

Castle的相关网站:

http://www.castleproject.org/
http://www.castleproject.org/projects/dynamicproxy/
http://sourceforge.net/projects/castleproject/

 

在Castle的2.5以上版本,已经将 Castle.DynamicProxy2.dll 里有内容,集成到 Castle.Core.dll 中。

所以,朋友们,不需要再去哪里找Castle.DynamicProxy2.dll了。

当然,除非你使用低于2.5的版本。

本文使用的Castle.Core.dll是3.1版本。

 

 

由于方法的拦载是动态构建类型,所以我们在拦截类方法时,可以采取用动态构造类的方式,从该类继承一个子类,重载并改写类中需要拦截的方法。

因此,我们不难理解,为什么在Castle 的 AOP中实现对类方法的拦截,都需要该类中的可被拦载的方法都是能够被子类重载的(override)。

 

CastleAOPTest.Lib.Person的代码

[csharp] view plain copy
 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5.   
  6. namespace CastleAOPTest.Lib  
  7. {  
  8.     public class Person  
  9.     {  
  10.         public virtual void SayHello()  
  11.         {  
  12.             Console.WriteLine("您好!");  
  13.         }  
  14.   
  15.         public virtual void SayName(string pHometown)  
  16.         {  
  17.             Console.WriteLine("我是天涯人,我来自:{0}。", pHometown);  
  18.         }  
  19.   
  20.         public void SayOther()  
  21.         {  
  22.             Console.WriteLine("是的,我是中国人。");  
  23.         }  
  24.   
  25.     }  
  26. }  

 

这个类型没什么好说的,只是输出一些字符串而以。

惟一需要注意的是:前两个方法都是虚方法,而“SayOther”不是虚方法,即是说“SayOther”不可以用一般的方式重载。

 

方法拦载器CastleAOPTest.Lib.AOP.SimpleInterceptor的代码:

[csharp] view plain copy
 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5.   
  6. using CastleAOPTest.Lib;  
  7. using Castle.DynamicProxy;  
  8.   
  9. namespace CastleAOPTest.Lib.AOP  
  10. {  
  11.     public class SimpleInterceptor : StandardInterceptor  
  12.     {  
  13.         protected override void PreProceed(IInvocation invocation)  
  14.         {  
  15.             Console.WriteLine("调用前的拦截器,方法名是:{0}。", invocation.Method.Name);  
  16.             base.PreProceed(invocation);  
  17.   
  18.         }  
  19.   
  20.         protected override void PerformProceed(IInvocation invocation)  
  21.         {  
  22.             Console.WriteLine("拦截的方法返回时调用的拦截器,方法名是:{0}。", invocation.Method.Name);  
  23.             base.PerformProceed(invocation);  
  24.   
  25.         }  
  26.   
  27.   
  28.         protected override void PostProceed(IInvocation invocation)  
  29.         {  
  30.             Console.WriteLine("调用后的拦截器,方法名是:{0}。", invocation.Method.Name);  
  31.             base.PostProceed(invocation);  
  32.   
  33.         }  
  34.     }  
  35. }  


 

Castle DynamicProxy提供了一个标准的方法拦截器,在一般的情况下,从这个标准的拦截器继承便可以完成大部分方法拦载上面的需求。

StandardInterceptor中提供了三个可重载的方法:


1.PreProcced,在进入拦截的方法之前调用。

2.PerformProceed,在拦截的方法返回时调用。

3.PostProcced,在拦截的方法运行完成后调用。

 

 

如何使用这个写好的拦截器

[csharp] view plain copy
 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5.   
  6. using Castle.DynamicProxy;  
  7. using CastleAOPTest.Lib;  
  8. using CastleAOPTest.Lib.AOP;   
  9.   
  10. namespace CastleAOPTest.Run  
  11. {  
  12.     class Program  
  13.     {  
  14.         static void Main(string[] args)  
  15.         {  
  16.             ProxyGenerator generator = new ProxyGenerator();//实例化【代理类生成器】  
  17.             SimpleInterceptor interceptor = new SimpleInterceptor();//实例化【拦截器】  
  18.   
  19.             //使用【代理类生成器】创建Person对象,而不是使用new关键字来实例化  
  20.             Person person = generator.CreateClassProxy<Person>(interceptor);  
  21.   
  22.   
  23.             Console.WriteLine("当前类型:{0},父类型:{1}",person.GetType(), person.GetType().BaseType);  
  24.             Console.WriteLine();  
  25.   
  26.   
  27.             person.SayHello();//跟普通调用没有两样吧?  
  28.             Console.WriteLine();  
  29.   
  30.             person.SayName("福建");//跟普通调用没有两样吧?  
  31.             Console.WriteLine();  
  32.   
  33.             person.SayOther();//它不是虚方法,无法拦截。待会检测输出情况就知道了。     
  34.   
  35.   
  36.   
  37.            Console.ReadLine();     
  38.   
  39.         }  
  40.     }  
  41. }  


 

ProxyGenerator其实是一个动态的类型构造器,它依据Person类型,并加入相应的拦载器构造出了一个新的类型,我们来查看一下运行输出:

技术分享

 

根据输出的第一行,我们可以知道,ProxyGenerator构造了一个新的类型,这个类型继承自Person。

由于这个类型的SayOther方法不可以被子类重载,所以这个方法无法被拦截。

Castle

标签:

原文地址:http://www.cnblogs.com/shijingjing07/p/5745374.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!