MSBuild + MSILInect实现编译时AOP-改变前后对比

简介:

    实现静态AOP,就需要我们在预编译时期,修改IL实现对代码逻辑的修改。Mono.Cecil就是一个很好的IL解析和注入框架,参见编译时MSIL注入--实践Mono Cecil(1)

  我的思路为:在编译时将加有继承制MethodInterceptBaseAttribute标签的原方法,重新组装成一个方法(并加上[CompilerGenerated]标签),在加入横切注入接口前后代码,调用此方法。

比如代码:

复制代码
[TestAOPAttribute(Order  =   1 )]

public  Class1 TestMethod1( int  i,  int  j, Class1 c) 
        { 
            Console.WriteLine(
" ok " ); 
            
return   new  Class1(); 
        }

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 

               
#endregion  
    }
复制代码

将会转化(实际注入IL,这里反编译为了c#代码,更清晰)为:

12

 

image

 

从这里你就会清晰的明白这里实现静态注入了机制和原理了。我们需要做的目的就是从IL出发改变原来代码逻辑,注入我们的截取代码。使用Mono.Cecil具体代码在程序包MethodILInjectTask中。

MatchedMethodInterceptBase是应用于class上匹配该class多个methodattribute基类。rule为匹配规则。

[TestAOP2Attribute(Rule  =   " TestMethod1* " )]

public   class  Class1 


   image

这里需要对于继承制该基类的标示class的所有满足rule的方法进行注入。

PropertyInterceptBase:属性注入,Action属性标识get,set方法。

复制代码
[TestAOPPropertyGetAttribute(Action  =  PropertyInterceptAction.Get)] 
       
public   int  TestProperty 
       { 
           
get
           
set
       }
复制代码

 

image

属性注入找出标示property,更具action选择get,set方法注入IL逻辑。

现在对于方法中获取attribute通过反射,性能存在一定问题。完全可以在class中注入属性,延时加载,Dictionary类级缓存来减少这方面损失,还暂时没考虑加入。

    不是很会写blog,所以有什么不明白的可留言,上一篇MSBuild + MSILInect实现编译时AOP之预览,由于时间写的没头没尾的,估计大家都看的很迷茫,迷茫该怎么写。关于IL注入Mono.Cecil可以参见编译时MSIL注入--实践Mono Cecil(1)和官方http://www.mono-project.com/Cecil。还有必须对MSIL具有一定了解(相同与Emit的IL注入)

   附带:源码下载


作者:破  狼 
出处:http://www.cnblogs.com/whitewolf/ 
本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。该文章也同时发布在我的独立博客中-个人独立博客博客园--破狼51CTO--破狼。http://www.cnblogs.com/whitewolf/archive/2011/08/09/2133106.html


相关文章
|
7月前
|
Java 数据库连接 API
Gradle依赖管理:编译时和运行时依赖的区别
Gradle依赖管理:编译时和运行时依赖的区别
50 0
|
11月前
VC 不同版本代码注入的改进
在上篇文章中 《VC 不同版本代码注入的区别》 ,我们想要对目标进程进行代码的注入,由于 Debug 版编译生成的代码和 Release 版编译生成的代码有些不同(Debug 版编译后,调用函数时会有一条 jmp 指令,而 Release 没有),因此,通过 #ifdef 这样的宏来区别 VC 是以 Debug 版方式编译,还是通过 Release 版方式编译,从而编译不同的代码来针对不同的版本进行了处理。
55 0
|
11月前
VC 不同版本代码注入的区别
VC 不同版本代码注入的区别
39 0
|
编译器 C++ Windows
Qt程序运行依赖环境打包方法:windeployqt方法
3分钟学会Qt程序运行依赖环境打包方法:windeployqt方法!
307 0
Qt程序运行依赖环境打包方法:windeployqt方法
|
Java Android开发
编译安卓项目时报错
编译安卓项目时报错
325 0
编译安卓项目时报错
|
数据可视化 C# C++
使用基于Roslyn的编译时AOP框架
介绍如何通过使用基于Roslyn的编译时AOP框架来解决.NET项目的代码复用问题。 可以在项目编译时自动插入指定代码,从而避免在运行时带来的性能消耗。
305 0
使用基于Roslyn的编译时AOP框架
【Groovy】编译时元编程 ( 编译时处理 ASTTransformation 接口实现 | 配置 ASTTransformation )
【Groovy】编译时元编程 ( 编译时处理 ASTTransformation 接口实现 | 配置 ASTTransformation )
196 0
【Groovy】编译时元编程 ( 编译时处理 ASTTransformation 接口实现 | 配置 ASTTransformation )
|
XML Java Android开发
【字节码插桩】Android 打包流程 | Android 中的字节码操作方式 | AOP 面向切面编程 | APT 编译时技术
【字节码插桩】Android 打包流程 | Android 中的字节码操作方式 | AOP 面向切面编程 | APT 编译时技术
210 0
【字节码插桩】Android 打包流程 | Android 中的字节码操作方式 | AOP 面向切面编程 | APT 编译时技术