在上两篇我们介绍了OnExceptionAspectOnMethodBoundaryAspect ,在这节我们将继续了解MethodInterceptionAspect,他为我们提供了关于方法处理的AOP切入,不同于OnMethodBoundaryAspect,他不是边界,是方法体。有了我们可以在我们的方法切入aspect很多有用的信息,比如将同步方法变为异步,防止多次点击重复提交,winform,wpf的多线程调用UI(参见PostSharp - Thread Dispatching(GUI多线程)),长时间操作在超过用户接受时间弹出进度条等等有用的关于用户体验和业务逻辑功能,简化我们的编程开发。

同样我们先来看看其MethodInterceptionAspect定义:

Invoke MethodInterceptionArgs参数:

我们一般使用Proceed是的方法进行处理。在这时我们可以加入线程池调用,使的其变为异步操作。

同时MethodInterceptionAspect 还继承了MethodLevelAspect 的CompileTimeValidate编译是验证,CompileTimeInitialize编译时初始化,RuntimeInitialize运行时初始化,后边的初始化我们将在后面一节PostSharp范围(static和instance中讲到)。

其定义很简单,在于我们的发挥:

二:防止多次提交处理demo:

我们这里只采用简单思路在方法进入禁止按钮可用,方法执行完成后恢复可用状态。我们将使监听winform事件处理方法,按钮来自EventHandle的第一个参数Sender。

 

  1. [Serializable]   
  2.     public class UnMutipleTriggerAttribute : MethodInterceptionAspect   
  3.     {   
  4.          
  5.  
  6. public override bool CompileTimeValidate(System.Reflection.MethodBase method)   
  7.        {   
  8.            var ps = method.GetParameters();   
  9.            if (ps != null && ps.Count() > 0 && ps[0].Name == "sender")   
  10.                return true;   
  11.            return false;   
  12.        }   
  13.  
  14.         public override void OnInvoke(MethodInterceptionArgs args)   
  15.         {   
  16.             if (args.Arguments.Count > 0)   
  17.             {   
  18.                 var controls = args.Arguments[0] as System.Windows.Forms.Control;   
  19.                 if (controls != null && controls.Enabled)   
  20.                 {   
  21.                     controls.Enabled = false;   
  22.                     args.Proceed(); ;   
  23.                     controls.Enabled = true;   
  24.                 }   
  25.             }   
  26.  
  27.         }   
  28.     } 

在这里我们是监听方法的处理事件函数根据vs自动生成规则,第一个参数是sender,事件源,这里利用了CompileTimeValidate在编译时决定是否注入aspect。

注意这里只是一个简单的demo,只针对于同步操作,如要变为异步操作,这需要改为在异步操作后启用。

测试在button点击方法加上attribute:

 
  1. [UnMutipleTriggerAttribute]   
  2.         private void Save(object sender, EventArgs e)   
  3.         {   
  4.             System.Threading.Thread.Sleep(2000);   
  5.         } 

效果:

这个例子很简单的就完成了。

demo下载

参考:

http://whitewolfblog.blog.51cto.com/addblog.php