单从Advice(通知)实现AOP2015-01-12如果你在实际开发中没感觉到OOP的一些缺陷,就不要往下看了!如果你不了解AOP,或类似AOP的思路,请先去了解一下AOP相关的认识。如果你是概念党,或是经验党,或是从众党,也请不要看了!我实现的只是一个小功能,是不是AOP我并不清楚,也不主要,标题那样写只是让大家一看就明白本文讲的大概是什么,况且我也想不出写个什么标题。因为我看了别人谈论的AOP,扯到好多东西,代理啦、emit啦等等天花乱坠的,不过一个也没看懂(I hate complex)!但有一点对我很有用,就是几种通知类型:1,目标方法调用前(before)2,目标方法调用后(after)---目标方法异常也执行3,目标方法返回后(after return)---目标方法异常不执行3,目标方法调用前后(around)4,目标方法抛出异常时(throw)我感觉稍微整理一下更好理解,所以下方的实现是基于这6种类型的:1,目标方法调用前(Before)2,目标方法调用后(After)--目标方法异常是不执行的!3,目标方法调用后(AfterEnsure) --目标方法异常也执行。4,目标方法调用前后(Around)--目标方法异常,After是不执行的5,目标方法调用前后(AroundEnsure)--目标方法异常,After也执行6,目标方法抛出异常时(Throw)考虑到多种通知处理,就需要一个统一接口(泛指接口), 而这里抽象类比.net接口更合适:(这个组件只有两个类,这是其中之一)
public abstract class AspectAdvice{public virtual void Before(object target, MethodInfo mi, params object[] args) { }public virtual void After(object target, MethodInfo mi, params object[] args) { }public virtual void Throw(object target, MethodInfo mi, params object[] args) { }}
三个方法就够了,这三个方法与目标方法不同的调用逻辑可以满足上面6种通知,下面再分析。为了好描述,我也以日志记录为例,下面分别是目标类,和日志类(可以叫它切面吗?呵呵)
public class MyClass{//无返回值public void Act(){Console.WriteLine("MyClass.Act()");}//有返回值public int Fun(string str){return str.Length;}private int m_num=10;//用到对象成员m_num,可能发生异常public int Divide(int n){return m_num / n;}//静态方法public static void SFun(string str){Console.WriteLine(str);}}