[转载]C#利用Emit反射实现AOP,以及平台化框架封装思路 – 以利亚 – 博客园.
这是前两天扒的一段动态代理AOP代码,用的Emit反射生成子类来实现代理模式,在这里做个小笔记,然后讨论一下AOP框架的实现思路。
首先是主函数:
static void Main(string[] args) { RealClass proxy = (RealClass)DynamicProxyBuilder.Wrap(typeof(RealClass)); proxy.Test(); Console.ReadKey(); }
用一个动态代理Builder包装了真实的被代理类,这是被代理类:
public class RealClass { public RealClass() { } //必须是虚方法 public virtual bool Test() { return false; } }
我们需要在Test执行前后做一些事情,也就是拦截器,这里以一个布尔值为例子,随便一写:
public class Interceptor { public Object Call(String methodName, MulticastDelegate methodDelegate, params Object[] args) { Object obj = null; try { Console.WriteLine("进入拦截器,执行之前方法"); obj = methodDelegate.Method.Invoke(methodDelegate.Target, args); if ((bool)obj) { Console.WriteLine("返回真"); } else { Console.WriteLine("返回假"); } Console.WriteLine("执行之后方法,离开拦截器"); } catch (ApplicationException ex) { Console.WriteLine("出现异常"); } return obj; } }
即,在主函数里通过一个“框架API”调用这个类的代理子类来执行拦截器里的方法,DynamicProxyBuilder类代码如下:
View Code
这个程序在运行时会在bin下创建一个DynamicProxy.dll,里面是用Emit反射生成的代理子类,复写了父类的方法。
上面的代码里有一个Interceptor类,封装AOP框架的一个思路就是把这个类提出一个接口,里面有之前、之后、异常等方法,然后让一个抽象类实现这个接口,提供空实现骨架(模板方法模式),把这个抽象类注入到子类构造器当中来构造子类。
如果要结合项目造轮子的话,则允许以这个接口为标准二次开发具体的拦截器,并且可以根据需求封装配置界面,来配置针对系统当中哪一个具体操作命令来进行拦截。
DynamicProxyBuilder.Wrap这个方法可以封装为一个人性化的框架接口(作为AOP框架的API)来创建代理子类。
有必要将拦截器类放入IoC容器当中以防每次反射。
最后,动态代理性能很差,至少第一次生成dll很慢,而且看不懂!
真不想用框架、要自己写AOP的话,还是直接让最终执行核心方法的类实现拦截器接口,然后直接在自己的框架里调接口吧,这样还看得懂,别搞什么Emit!
最后引用马老师的一句经典语录——搞毛飞机啊!