1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | private static void SayHello( string user, string title) { Console.WriteLine( string .Format( "Hello {0} {1}" , title, user)); } private static void ThrowException() { throw new Exception( "I'm a test message." ); } static void Main( string [] args) { SayHello( "Richie" , "Mr." ); try { ThrowException(); } catch { } Console.ReadKey(); return ; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | [Serializable] public class OnMyExceptionAspect : OnMethodBoundaryAspect { public override void OnEntry(MethodExecutionEventArgs eventArgs) { base .OnEntry(eventArgs); Console.WriteLine( string .Format( "Entering method: {0}" , eventArgs.Method.Name)); object [] arguments = eventArgs.GetReadOnlyArgumentArray(); ParameterInfo[] parameters = eventArgs.Method.GetParameters(); for ( int i = 0; arguments != null && i < arguments.Length; i++) Console.WriteLine( string .Format( " arg{0} {1}: {2}" , i + 1, parameters[i].Name, arguments[i])); } public override void OnExit(MethodExecutionEventArgs eventArgs) { base .OnExit(eventArgs); Console.WriteLine( string .Format( "Exiting method: {0}" , eventArgs.Method.Name)); } public override void OnException(MethodExecutionEventArgs eventArgs) { Console.WriteLine( "There's an error occured:" + eventArgs.Exception.Message); base .OnException(eventArgs); } } |
using System;
using System.ComponentModel;
using System.Reflection;
using PostSharp.Extensibility;
using PostSharp.Laos;
我们用下面的PropertyChangedNotificationAttribute来实现对象属性更改通知: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | [Serializable] [MulticastAttributeUsage(MulticastTargets.Method)] public class PropertyChangedNotificationAttribute : OnMethodBoundaryAspect { private object _preValue; public override void OnExit(MethodExecutionEventArgs eventArgs) { base .OnExit(eventArgs); if (!eventArgs.Method.IsSpecialName) return ; if (!eventArgs.Method.Name.StartsWith( "get_" ) && !eventArgs.Method.Name.StartsWith( "set_" )) return ; bool isSetter = eventArgs.Method.Name.StartsWith( "set_" ); string property = eventArgs.Method.Name.Substring(4); if (isSetter) Console.WriteLine( string .Format( "Property \"{0}\" was changed from \"{1}\" to \"{2}\"." , property , this ._preValue , this .GetPropertyValue(eventArgs.Instance, property))); else Console.WriteLine( string .Format( "Property \"{0}\" was read." , property)); } public override void OnEntry(MethodExecutionEventArgs eventArgs) { base .OnEntry(eventArgs); //记录属性更改前的值 if (!eventArgs.Method.IsSpecialName) return ; if (!eventArgs.Method.Name.StartsWith( "set_" )) return ; string property = eventArgs.Method.Name.Substring(4); this ._preValue = this .GetPropertyValue(eventArgs.Instance, property); } private object GetPropertyValue( object instance, string property) { PropertyInfo getter = instance.GetType().GetProperty(property); return getter.GetValue(instance, null ); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | [PropertyChangedNotification] public class Person { private string firstName; private string lastName; public Person( string first, string last) { this .firstName = first; this .lastName = last; } public string FirstName { get { return firstName; } set { firstName = value; } } public string LastName { get { return lastName; } set { lastName = value; } } public string Name { get { return this .FirstName + " " + this .LastName; } } } <BR> static void Main( string [] args) { Person user = new Person( "Richie" , "Liu" ); user.FirstName = "RicCC" ; Console.WriteLine( string .Format( "{ { {0} {1} }}" , user.FirstName, user.LastName)); Console.ReadKey(); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | [Serializable] public sealed class CacheAttribute : OnMethodBoundaryAspect { // 用来生成缓存的key值,key值中包含方法名、参数值等,因此参数不一时方法会被执行 private MethodFormatStrings formatStrings; // 用于缓存 private static readonly Dictionary<STRING, object = "" > cache = new Dictionary<STRING, object = "" >(); <BR> // 编译时刻执行的方法 // Cache这个attribute用于方法上,某些方法不允许使用缓存,将在下面进行检查 public override bool CompileTimeValidate(MethodBase method) { // Don't apply to constructors. if (method is ConstructorInfo) { Message.Write(SeverityType.Error, "CX0001" , "Cannot cache constructors." ); return false ; } MethodInfo methodInfo = (MethodInfo)method; // Don't apply to void methods. if (methodInfo.ReturnType.Name == "Void" ) { Message.Write(SeverityType.Error, "CX0002" , "Cannot cache void methods." ); return false ; } // Does not support out parameters. ParameterInfo[] parameters = method.GetParameters(); for ( int i = 0; i < parameters.Length; i++) { if (parameters[i].IsOut) { Message.Write(SeverityType.Error, "CX0003" , "Cannot cache methods with return values." ); return false ; } } return true ; } // 编译时刻执行的方法 public override void CompileTimeInitialize(MethodBase method, AspectInfo aspectInfo) { this .formatStrings = Formatter.GetMethodFormatStrings(method); } <BR> public override void OnEntry(MethodExecutionArgs eventArgs) { //生成缓存的key值 string key = this .formatStrings.Format( eventArgs.Instance, eventArgs.Method, eventArgs.Arguments.ToArray()); lock (cache) { object value; //查看是否存在缓存 if (!cache.TryGetValue(key, out value)) // 缓存不存在,继续执行这个方法,并将key存在MethodExecutionTag,在执行完毕的 // OnSuccess事件时使用key值将结果放到缓存中 eventArgs.MethodExecutionTag = key; else { // 已经在缓存中存在,则将执行的返回值直接设置为缓存中的值,不执行方法体而立即返回 eventArgs.ReturnValue = value; eventArgs.FlowBehavior = FlowBehavior.Return; } } } <BR> //这个事件只有在方法体被执行了,并且执行成功没有异常发生时才会触发 public override void OnSuccess(MethodExecutionArgs eventArgs) { // 取得缓存的key值 string key = ( string )eventArgs.MethodExecutionTag; // 把执行结果放入缓存中 lock (cache) { cache[key] = eventArgs.ReturnValue; } } }</STRING,></STRING,> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public static void Main( string [] args ) { Console.WriteLine( "1 ->" + GetDifficultResult( 1 ) ); Console.WriteLine( "2 ->" + GetDifficultResult( 2 ) ); Console.WriteLine( "1 ->" + GetDifficultResult( 1 ) ); Console.WriteLine( "2 ->" + GetDifficultResult( 2 ) ); Console.ReadKey(); } [Cache] private static int GetDifficultResult( int arg ) { // 如果方法体被执行了,则会输出下面的消息,否则不会输出,说明使用了缓存 Console.WriteLine( "Some difficult work!" ); Thread.Sleep( 1000 ); return arg; } |
1 2 3 4 5 6 7 8 9 10 | [DbInvoke( "ConnectionString" )] internal static class DataLayer { #pragma warning disable 626 extern static public void CreateCustomer( string customerName, out int customerId); extern static public void ModifyCustomer( int customerId, string customerName); extern static public void DeleteCustomer( int customerId); extern static public void ReadCustomer( int customerId, out string customerName); #pragma warning restore 626 } |