AOP(基于切面编程):它是对业务逻辑的分离,使各个业务直接的耦合变低,比如在传统的OOP编程中将日志记录、异常处理、权限管理等方面剥离出来。在 今后的维护过程中,对其改变日志记录、异常处理、权限管理方法的时候,不用去改变主业务流程逻辑代码。提高开发效率。

        PostSharp采用特性的方式来对编译后的主业务流程方法逻辑横向静态注入截取数据。下面我们将以一个实例来演示如何使用PostSharp实现AOP进行日志记录和异常处理。

        首先需要安装PostSharp 2.1.4.1免费版本,这个版本只是功能相对较少,可商用,能够满足日志记录和异常截取的要求。点击PostSharp-2.1.4.1 下载.      

        然后新建一个控制台项目并将PostSharp.dll引入该项目中。编写一个截取日志的特性LogsAttributes.cs。

 

  1. //日志特性截取类 
  2. [Serializable
  3. [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)] 
  4. class LogsAttribute:OnMethodBoundaryAspect 
  5.     ///<summary> 
  6.     /// 入口参数信息 
  7.     ///</summary> 
  8.     public string EntryText { get; set; } 
  9.  
  10.     ///<summary> 
  11.     /// 出口参数信息 
  12.     ///</summary> 
  13.     public string ExitText { get; set; } 
  14.  
  15.     ///<summary> 
  16.     /// 异常信息 
  17.     ///</summary> 
  18.     public string ExceptionText { get; set; } 
  19.  
  20.     //进入函数时输出函数的输入参数 
  21.     public override void OnEntry(MethodExecutionArgs eventArgs) 
  22.     { 
  23.         Arguments arguments = eventArgs.Arguments; 
  24.         StringBuilder sb = new StringBuilder(); 
  25.         ParameterInfo[] parameters = eventArgs.Method.GetParameters(); 
  26.         for (int i = 0; arguments != null && i < arguments.Count; i++) 
  27.         { 
  28.             //进入的参数的值 
  29.             sb.Append( parameters[i].Name + "=" + arguments[i] + ""); 
  30.         } 
  31.         string message = string.Format("{0}.{1} Method. The Entry Arg Is:{2}"
  32.             eventArgs.Method.DeclaringType.FullName, eventArgs.Method.Name, sb.ToString()); 
  33.         Console.WriteLine(message); 
  34.     } 
  35.  
  36.     //退出函数时的函数返回值 
  37.     public override void OnExit(MethodExecutionArgs eventArgs) 
  38.     { 
  39.         Console.WriteLine(string.Format("{0}.{1} Method. The Result Is:{2}",  
  40.             eventArgs.Method.DeclaringType.FullName, eventArgs.Method.Name, eventArgs.ReturnValue.ToString())); 
  41.     } 
  42.  
  43.     //函数发生异常时记录异常信息 
  44.     public override void OnException(MethodExecutionArgs eventArgs) 
  45.     { 
  46.         Console.WriteLine(string.Format("{0}.{1} Method. The Exception Is:{2}"
  47.             eventArgs.Method.DeclaringType.FullName, eventArgs.Method.Name, eventArgs.Exception.Message)); 
  48.          
  49.     } 

        再看看当出现异常时通过try{} catch{}处理异常,ExceptionAttribute.cs类捕捉并且处理异常:

 

  1. //截取异常并且处理异常 
  2. [Serializable
  3. [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)] 
  4. class ExceptionAttribute:MethodInterceptionAspect 
  5.     //调用本函数时截取异常 
  6.     public override void  OnInvoke(MethodInterceptionArgs args) 
  7.     { 
  8.         try 
  9.         { 
  10.              base.OnInvoke(args); 
  11.         } 
  12.         catch(Exception ex) 
  13.         { 
  14.             Console.WriteLine(string.Format("此方法异常信息是:{0}", ex.ToString())); 
  15.         } 
  16.     } 

        在客户端编写两个方法来测试PostSharp是否静态注入并且捕获到相关信息,代码如下:

 

  1. class Program 
  2.     static void Main(string[] args) 
  3.     { 
  4.         Add(3, 5); 
  5.         Console.WriteLine("-------------------------------------------------------"); 
  6.         Subject(5, 12); 
  7.         Console.ReadLine(); 
  8.     } 
  9.  
  10.     //此函数让我们看其输入参数和返回值的日志记录 
  11.     [Logs] 
  12.     [Exception] 
  13.     public static int Add(int a, int b) 
  14.     { 
  15.         return a + b;    
  16.     } 
  17.  
  18.     //此函数看我们的异常通过自定义Exception特性记录下来 
  19.     [Logs] 
  20.     [Exception] 
  21.     public static int Subject(int a, int b) 
  22.     { 
  23.  
  24.         throw new ArgumentException("减法出现异常,需要处理"); 
  25.         
  26.         return a - b; 
  27.     } 

        下面是项目运行效果,如需源码请点击 PostSharpAOP.zip 下载。