Postsharp基本用法——方法、屬性攔截與異常處理

以下Demo代碼基於 .NET Core 演示了Postsharp的基本使用方法,稍作修改(反射部分有些許差異)也適用於.NET Framework。

更多高級使用方法詳見官方文檔。http://samples.postsharp.net/

 

  1 using System;
  2 using System.Linq;
  3 using PostSharp.Aspects;
  4 using PostSharp.Serialization;
  5 
  6 namespace NetCoreConsole
  7 {
  8   class Program
  9   {
 10     static void Main(string[] args)
 11     {
 12       var result = Calc(5, 6);
 13       Console.WriteLine($"計算結果:{result}");
 14       Console.WriteLine(">>>>>>>>>>>>>>方法攔截測試完畢\r\n");
 15 
 16 
 17       PropertyTest = -1;
 18       Console.WriteLine(">>>>>>>>>>>>>>屬性攔截測試(setter)完畢\r\n");
 19 
 20 
 21       var x = PropertyTest;
 22       Console.WriteLine(">>>>>>>>>>>>>>屬性攔截測試(getter)完畢\r\n");
 23 
 24       Console.ReadKey();
 25     }
 26 
 27 
 28     /// <summary>
 29     /// 方法攔截測試 + 異常處理
 30     /// </summary>
 31     /// <param name="x"></param>
 32     /// <param name="y"></param>
 33     /// <returns></returns>
 34     [HowToUse, ExceptionHandle]
 35     private static int Calc(int x, int y)
 36     {
 37       int a = 1;
 38       int b = 0;
 39       int c = a / b;
 40 
 41       return x + y;
 42     }
 43 
 44     private static int _propertyTest;
 45 
 46     /// <summary>
 47     /// 屬性攔截測試
 48     /// 注:可以標記在整個屬性上,也可以分別單獨標記在 【getter】 或者 【setter】 上
 49     /// </summary>
 50     [HowToUse, ExceptionHandle]
 51     private static int PropertyTest
 52     {
 53 
 54       get
 55       {
 56         return _propertyTest;
 57       }
 58 
 59       // [HowToUse]
 60       set
 61       {
 62         if (value <= 0)
 63         {
 64           throw new ArgumentException($"屬性值必須大於0");
 65         }
 66 
 67         _propertyTest = value;
 68       }
 69     }
 70   }
 71 }
 72 
 73 /// <summary>
 74 /// 方法攔截測試
 75 /// </summary>
 76 [PSerializable]
 77 [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property)]
 78 public class HowToUseAttribute : MethodInterceptionAspect
 79 {
 80   /// <summary>
 81   /// 方法執行攔截
 82   /// </summary>
 83   /// <param name="args"></param>
 84   public override void OnInvoke(MethodInterceptionArgs args)
 85   {
 86     var methodBase = args.Method;
 87 
 88     // 如果是 .NET Framework 這裏的System.Reflection.MethodInfo 應該替換爲 System.Reflection.RuntimeMethodInfo
 89     var returnType = ((System.Reflection.MethodInfo)methodBase).ReturnType.FullName;
 90      
 91     // 方法形式參數列表字符
 92     var paramListString = methodBase.GetParameters().Aggregate(string.Empty,
 93       (current, parameter) => current + $"{parameter.ParameterType.FullName} {parameter.Name}, ").Trim(',', ' ');
 94 
 95     // 方法簽名
 96     // var signatures =  $"{returnType} {methodBase.Name}({paramListString})";
 97     var signatures = methodBase.ToString();
 98 
 99     Console.WriteLine($"被攔截的方法簽名:{signatures}");
100 
101     // 方法實際參數列表字符
102     var argsString = args.Arguments
103       .Aggregate(string.Empty, (current, p) => current + $"{p.GetType().FullName} ---> 值:{p}, ").Trim(',', ' ');
104 
105     Console.WriteLine($"被攔截的方法輸入參數:{argsString}");
106 
107     // 處理(執行被攔截的方法)
108     args.Proceed();
109 
110     // 異步執行
111     // args.ProceedAsync();
112 
113     var returnValue = args.ReturnValue;
114 
115     Console.WriteLine($"方法返回值:{returnValue}");
116   }
117 }
118 
119 /// <summary>
120 /// 異常處理
121 /// </summary>
122 [PSerializable]
123 [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property)]
124 public class ExceptionHandleAttribute : OnExceptionAspect
125 {
126   public override void OnException(MethodExecutionArgs args)
127   {
128     // 設置流程行爲(繼續執行,不拋出)
129     args.FlowBehavior = FlowBehavior.Continue;
130 
131     Console.WriteLine($"發生異常:{args.Exception.GetType().FullName} ----> {args.Exception.Message}");
132   }
133 }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章