Castle的相关网站:
http://www.castleproject.org/
http://www.castleproject.org/projects/dynamicproxy/
http://sourceforge.net/projects/castleproject/
所以,朋友们,不需要再去哪里找Castle.DynamicProxy2.dll了。
当然,除非你使用低于2.5的版本。
本文使用的Castle.Core.dll是3.1版本。
由于方法的拦载是动态构建类型,所以我们在拦截类方法时,可以采取用动态构造类的方式,从该类继承一个子类,重载并改写类中需要拦截的方法。
因此,我们不难理解,为什么在Castle 的 AOP中实现对类方法的拦截,都需要该类中的可被拦载的方法都是能够被子类重载的(override)。
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace CastleAOPTest.Lib { public class Person { public virtual void SayHello() { Console.WriteLine("您好!"); } public virtual void SayName(string pHometown) { Console.WriteLine("我是天涯人,我来自:{0}。", pHometown); } public void SayOther() { Console.WriteLine("是的,我是中国人。"); } } }
这个类型没什么好说的,只是输出一些字符串而以。
惟一需要注意的是:前两个方法都是虚方法,而“SayOther”不是虚方法,即是说“SayOther”不可以用一般的方式重载。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using CastleAOPTest.Lib; using Castle.DynamicProxy; namespace CastleAOPTest.Lib.AOP { public class SimpleInterceptor : StandardInterceptor { protected override void PreProceed(IInvocation invocation) { Console.WriteLine("调用前的拦截器,方法名是:{0}。", invocation.Method.Name); base.PreProceed(invocation); } protected override void PerformProceed(IInvocation invocation) { Console.WriteLine("拦截的方法返回时调用的拦截器,方法名是:{0}。", invocation.Method.Name); base.PerformProceed(invocation); } protected override void PostProceed(IInvocation invocation) { Console.WriteLine("调用后的拦截器,方法名是:{0}。", invocation.Method.Name); base.PostProceed(invocation); } } }
Castle DynamicProxy提供了一个标准的方法拦截器,在一般的情况下,从这个标准的拦截器继承便可以完成大部分方法拦载上面的需求。
StandardInterceptor中提供了三个可重载的方法:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Castle.DynamicProxy; using CastleAOPTest.Lib; using CastleAOPTest.Lib.AOP; namespace CastleAOPTest.Run { class Program { static void Main(string[] args) { ProxyGenerator generator = new ProxyGenerator();//实例化【代理类生成器】 SimpleInterceptor interceptor = new SimpleInterceptor();//实例化【拦截器】 //使用【代理类生成器】创建Person对象,而不是使用new关键字来实例化 Person person = generator.CreateClassProxy<Person>(interceptor); Console.WriteLine("当前类型:{0},父类型:{1}",person.GetType(), person.GetType().BaseType); Console.WriteLine(); person.SayHello();//跟普通调用没有两样吧? Console.WriteLine(); person.SayName("福建");//跟普通调用没有两样吧? Console.WriteLine(); person.SayOther();//它不是虚方法,无法拦截。待会检测输出情况就知道了。 Console.ReadLine(); } } }
ProxyGenerator其实是一个动态的类型构造器,它依据Person类型,并加入相应的拦载器构造出了一个新的类型,我们来查看一下运行输出:
根据输出的第一行,我们可以知道,ProxyGenerator构造了一个新的类型,这个类型继承自Person。
由于这个类型的SayOther方法不可以被子类重载,所以这个方法无法被拦截。
源码下载:http://download.csdn.net/detail/liuweitoo/4750999