在本文之前的前几篇浅谈.NET编译时注入(C#-->IL)、浅谈VS编译自定义编译任务—MSBuild Task(csproject)、编译时MSIL注入--实践Mono Cecil(1)已经讨论了MSBuild和Mono.Cicel。在这里我们将会利用它来实现一个简单的编译时AOP注入机制(这里所说的编译时是指c#到MSIL的预编译过程)。我更倾向于像EL(微软企业库框架)这类动态AOP。编译时AOP有PostSharp这种被称之为静态AOP框架,其优势在于直接代码语句,性能更好,它不需要我们多余的代码,像EL这种动态AOP,一般我们是不能直接new一个对象,需要容器(Container),在一些你的框架应用种,有时就需要使用者了解,再入我们对于WinForm、WebForm等.net平台上主流的基于微软事件机制的框架,事件方法的截获,往往我们需要改变、包装。在这时静态AOP就显出了他的优势。
Class Diagram:

1:IMethodInject:Interface,拥有Executeing,Exceptioned,ExecuteSuccess三个契约为别为执行前,异常,成功。它们都有公同的参数类型:MethodExecutionEventArgs
  
Executeing:返回值为bool类型,将决定是否继续执行方法体。Exceptioned:属性Eeption代表发生的异常信息,返回值ExceptionStrategy(取值:Handle, ReThrow, ThrowNew)决定异常处理机制,Handle已处理并忽略,ReThrow重新抛出,ThrowNew抛出一个包装后的来源于MethodExecutionEventArgs 的Exception。ExecuteSuccess,对于拥有返回值的方法,可以修改MethodExecutionEventArgs 的ReturnValue,修改返回值。最后MethodExecutionEventArgs的Order决定多个Attribute的注入先后,即方法截获的先后顺序。
1:MethodInterceptBase:针对于方法Attribute标签,实现方法截获View Code 
- [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]  
 -     public class MethodInterceptBase : Attribute, IMethodInject  
 -     {  
 -         public int Order 
 -         {  
 -             get;  
 -             set;  
 -         }  
 -         #region IMethodInject Members  
 -  
 -         public virtual bool Executeing(MethodExecutionEventArgs args)  
 -         {  
 -             return true;  
 -         }  
 -  
 -         public virtual ExceptionStrategy Exceptioned(MethodExecutionEventArgs args)  
 -         {  
 -             return ExceptionStrategy.ReThrow;  
 -         }  
 -  
 -         public virtual void ExecuteSuccess(MethodExecutionEventArgs args)  
 -         {  
 -  
 -         }  
 -          
 -         #endregion  
 - }  
 - 复制代码 
 
 
2:
MatchedMethodInterceptBase:和上面方法之上的MethodInterceptBase大体一致,区别在于其应用于class之上,属性Rule为截获方法匹配(应用于多个方法之上相同截获),支持*匹配。
 
 
- View Code   
 -    
 - [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]  
 -  
 -     public class MatchedMethodInterceptBase : Attribute, IMethodInject  
 -  
 -     {  
 -  
 -         public int Order 
 -  
 -         {  
 -  
 -             get;  
 -  
 -             set;  
 -  
 -         }  
 -  
 -    
 -  
 -         public string Rule 
 -  
 -         {  
 -  
 -             get;  
 -  
 -             set;  
 -  
 -         }  
 -  
 -         #region IMethodInject Members  
 -  
 -  
 -         public virtual bool Executeing(MethodExecutionEventArgs args)  
 -  
 -         {  
 -  
 -             return true;  
 -  
 -         }  
 -    
 -  
 -         public virtual ExceptionStrategy Exceptioned(MethodExecutionEventArgs args)  
 -  
 -         {  
 -  
 -             return ExceptionStrategy.ReThrow;  
 -  
 -         }  
 -  
 -    
 -  
 -         public virtual void ExecuteSuccess(MethodExecutionEventArgs args)  
 -  
 -         {  
 -  
 -    
 -  
 -         }  
 -  
 -          
 -  
 -         #endregion  
 -  
 -     }  
 - 复制代码 
 
3:PropertyInterceptBase:实现属性的注入,其属性Action(enum PropertyInterceptAction:None Get, Set)指注入属性的get或者Set;View Code 
 
其上默认都是Executeing继续执行,Exceptioned为抛出不处理,成功不修改result。
下面是一个简单测试Code:
- View Code   
 -  
 - using System;  
 -  
 - using System.Collections.Generic;  
 -  
 - using System.Linq;  
 -  
 - using System.Text;  
 -  
 - using System.Reflection;  
 -  
 - using Green.AOP;  
 -  
 -    
 -  
 - namespace Test  
 -  
 - {     
 -  
 -     // [TestAOP2Attribute(Rule = "TestMethod1*")]  
 -  
 -     public class Class1  
 -  
 -     {  
 -  
 -         // [TestAOPPropertyAttribute(Action = PropertyInterceptAction.Set)]  
 -  
 -         [TestAOPPropertyGetAttribute(Action = PropertyInterceptAction.Get)]  
 -  
 -         public testStrust TestProperty  
 -  
 -         {  
 -  
 -             get;  
 -  
 -             set;  
 -  
 -         }  
 -  
 -         [Obsolete()]  
 -  
 -         public static void Main(string[] args)  
 -  
 -         {            
 -  
 -             try  
 -  
 -             {  
 -  
 -                 var y = new Class1();  
 -  
 -                 // y.TestProperty = DateTime.Now;  
 -  
 -                 Console.WriteLine(y.TestProperty);  
 -  
 -             }  
 -  
 -             catch (Exception ex)  
 -  
 -             {  
 -  
 -                 Console.WriteLine(ex.ToString());  
 -  
 -             }  
 -  
 -             // new Class1().TestMethod1(1, 2, null);  
 -  
 -             Console.Read();  
 -  
 -             //throw new Exception("exfffffffffffffffffffff");  
 -  
 -         }  
 -  
 -         //[TestAOPAttribute(Order=1)]  
 -  
 -         //[TestAOP1Attribute(TestProperty = 1, Template = "sdsdsd",Order=0)]  
 -  
 -         public Class1 TestMethod1(int i, int j, Class1 c)  
 -  
 -         {  
 -  
 -             Console.WriteLine("ok");  
 -  
 -             return new Class1();  
 -  
 -         }  
 -  
 -     }  
 -  
 -     public class TestAOPPropertyGetAttribute : Green.AOP.PropertyInterceptBase  
 -  
 -     {  
 -  
 -         #region IMethodInject Members  
 -  
 -         public override bool Executeing(Green.AOP.MethodExecutionEventArgs args)  
 -  
 -         {  
 -  
 -             Console.WriteLine("------------------" + args);  
 -  
 -             Console.WriteLine(args.Instance);  
 -  
 -             Console.WriteLine(args.Method);  
 -  
 -             Console.WriteLine(this.GetType() + ":" + "Executeing");  
 -  
 -             return true;  
 -  
 -         }  
 -  
 -         public override Green.AOP.ExceptionStrategy Exceptioned(Green.AOP.MethodExecutionEventArgs args)  
 -  
 -         {  
 -  
 -             Console.WriteLine(this.GetType() + ":" + "Exceptioned");  
 -  
 -             return Green.AOP.ExceptionStrategy.ReThrow;  
 -  
 -         }  
 -  
 -         public override void ExecuteSuccess(Green.AOP.MethodExecutionEventArgs args)  
 -  
 -         {  
 -  
 -             Console.WriteLine("-----------");  
 -  
 -             Console.WriteLine(this.GetType() + ":" + "ExecuteSuccess" + "--result:" + args.ReturnValue);  
 -  
 -         }  
 -  
 -         #endregion  
 -  
 -     }  
 -  
 -     public class TestAOPPropertyAttribute : Green.AOP.PropertyInterceptBase  
 -  
 -     {  
 -  
 -         #region IMethodInject Members  
 -  
 -         public override bool Executeing(Green.AOP.MethodExecutionEventArgs args)  
 -  
 -         {  
 -  
 -             Console.WriteLine(args.Instance);  
 -  
 -             Console.WriteLine(args.Method);  
 -  
 -             Console.WriteLine(this.GetType() + ":" + "Executeing");  
 -  
 -             return true;  
 -  
 -         }  
 -  
 -         public override Green.AOP.ExceptionStrategy Exceptioned(Green.AOP.MethodExecutionEventArgs args)  
 -  
 -         {  
 -  
 -             Console.WriteLine(this.GetType() + ":" + "Exceptioned");  
 -  
 -             return Green.AOP.ExceptionStrategy.Handle;  
 -  
 -         }  
 -  
 -         public override void ExecuteSuccess(Green.AOP.MethodExecutionEventArgs args)  
 -  
 -        {  
 -  
 -             Console.WriteLine(this.GetType() + ":" + "ExecuteSuccess");  
 -  
 -         }  
 -  
 -         #endregion  
 -  
 -     }  
 -  
 -     public class TestAOP2Attribute : Green.AOP.MatchedMethodInterceptBase  
 -  
 -     {  
 -  
 -         #region IMethodInject Members  
 -  
 -         public override bool Executeing(Green.AOP.MethodExecutionEventArgs args)  
 -  
 -         {  
 -  
 -             Console.WriteLine(args.Instance);  
 -  
 -             Console.WriteLine(args.Method);  
 -  
 -             Console.WriteLine(this.GetType() + ":" + "Executeing");  
 -  
 -             return true;  
 -  
 -         }  
 -  
 -         public override Green.AOP.ExceptionStrategy Exceptioned(Green.AOP.MethodExecutionEventArgs args)  
 -  
 -         {  
 -  
 -             Console.WriteLine(this.GetType() + ":" + "Exceptioned");  
 -  
 -             return Green.AOP.ExceptionStrategy.Handle;  
 -  
 -         }  
 -  
 -         public override void ExecuteSuccess(Green.AOP.MethodExecutionEventArgs args)  
 -  
 -         {  
 -  
 -             Console.WriteLine(this.GetType() + ":" + "ExecuteSuccess");  
 -  
 -         }  
 -  
 -         #endregion  
 -  
 -         #region IMethodInject Members  
 -  
 -         public bool Match(System.Reflection.MethodBase method)  
 -  
 -         {  
 -  
 -             return true;  
 -  
 -         }  
 -  
 -         #endregion  
 -  
 -     }  
 -  
 -    
 -  
 -     //[AttributeUsage(AttributeTargets.Method)]  
 -  
 -     public class TestAOPAttribute : Green.AOP.MethodInterceptBase  
 -  
 -     {  
 -  
 -         #region IMethodInject Members  
 -  
 -         public override bool Executeing(Green.AOP.MethodExecutionEventArgs args)  
 -  
 -         {  
 -  
 -             Console.WriteLine(this.GetType() + ":" + "Executeing");  
 -  
 -             return true;  
 -  
 -         }  
 -  
 -    
 -  
 -         public override Green.AOP.ExceptionStrategy Exceptioned(Green.AOP.MethodExecutionEventArgs args)  
 -  
 -         {  
 -  
 -             Console.WriteLine(this.GetType() + ":" + "Exceptioned");  
 -  
 -             return Green.AOP.ExceptionStrategy.Handle;  
 -  
 -         }  
 -  
 -    
 -  
 -         public override void ExecuteSuccess(Green.AOP.MethodExecutionEventArgs args)  
 -  
 -         {  
 -  
 -             Console.WriteLine(this.GetType() + ":" + "ExecuteSuccess");  
 -  
 -         }  
 -  
 -    
 -  
 -         #endregion  
 -  
 -    
 -  
 -         #region IMethodInject Members  
 -  
 -    
 -  
 -    
 -  
 -         public bool Match(System.Reflection.MethodBase method)  
 -  
 -         {  
 -  
 -             return true;  
 -  
 -         }  
 -  
 -    
 -  
 -         #endregion  
 -  
 -     }  
 -  
 -    
 -  
 -     [AttributeUsage(AttributeTargets.Method)]  
 -  
 -     public class TestAOP1Attribute : Attribute, Green.AOP.IMethodInject  
 -  
 -     {  
 -  
 -         public int Order 
 -  
 -         {  
 -  
 -             get;  
 -  
 -             set;  
 -  
 -         }  
 -  
 -    
 -  
 -         public int TestProperty  
 -  
 -         {  
 -  
 -             get;  
 -  
 -             set;  
 -  
 -         }  
 -  
 -    
 -  
 -         public string Template  
 -  
 -         {  
 -  
 -             get;  
 -  
 -             set;  
 -  
 -         }  
 -  
 -    
 -  
 -         #region IMethodInject Members  
 -  
 -    
 -  
 -         public bool Executeing(Green.AOP.MethodExecutionEventArgs args)  
 -  
 -         {  
 -  
 -             Console.WriteLine(this.GetType() + ":" + "Executeing");  
 -  
 -             return true;  
 -  
 -         }  
 -  
 -    
 -  
 -         public Green.AOP.ExceptionStrategy Exceptioned(Green.AOP.MethodExecutionEventArgs args)  
 -  
 -         {  
 -  
 -             Console.WriteLine(this.GetType() + ":" + "Exceptioned");  
 -  
 -             return Green.AOP.ExceptionStrategy.Handle;  
 -  
 -         }  
 -  
 -    
 -  
 -         public void ExecuteSuccess(Green.AOP.MethodExecutionEventArgs args)  
 -  
 -         {  
 -  
 -             Console.WriteLine(this.GetType() + ":" + "ExecuteSuccess");  
 -  
 -         }  
 -  
 -    
 -  
 -         #endregion  
 -  
 -    
 -  
 -         #region IMethodInject Members  
 -  
 -    
 -  
 -    
 -  
 -         public bool Match(System.Reflection.MethodBase method)  
 -  
 -         {  
 -  
 -             return true;  
 -  
 -         }  
 -  
 -    
 -  
 -         #endregion  
 -  
 -     }  
 -  
 -    
 -  
 - }  
 - 复制代码 
 
注意测试有两种方式(由于没有安装包):
1:先重编译测试项目,运行ConsoleApplication2(在属性中修改控制台其实参数)。在查看测试项目。
2:将项目ConsoleApplication2修改为类库,在添加修改csprojec信息,Task位于Green.AOP.MyBuildTask,具体可以参见上一篇浅谈VS编译自定义编译任务—MSBuild Task(csproject)。
在后续将会从简单Demo分析实现原理。
- [AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)]  
 -     public class PropertyInterceptBase : Attribute, IMethodInject  
 -     {  
 -         public PropertyInterceptAction Action 
 -         {  
 -             get;  
 -             set;  
 -         }  
 -  
 -         public int Order 
 -         {  
 -             get;  
 -             set;  
 -         }  
 -         #region IMethodInject Members  
 -  
 -         public virtual bool Executeing(MethodExecutionEventArgs args)  
 -         {  
 -             return true;  
 -         }  
 -  
 -         public virtual ExceptionStrategy Exceptioned(MethodExecutionEventArgs args)  
 -         {  
 -             return ExceptionStrategy.ReThrow;  
 -         }  
 -  
 -         public virtual void ExecuteSuccess(MethodExecutionEventArgs args)  
 -         {  
 -  
 -         }  
 -  
 -         #endregion  
 -     }  
 - 复制代码