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#代码,更清晰)为:

 

 

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

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

[TestAOP2Attribute(Rule = "TestMethod1*")]

public class Class1 

   

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

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

[TestAOPPropertyGetAttribute(Action = PropertyInterceptAction.Get)] 
       public int TestProperty 
       { 
           get; 
           set; 
       }

 

属性注入找出标示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

时间: 2024-08-26 11:01:07

MSBuild + MSILInect实现编译时AOP-改变前后对比的相关文章

MSBuild + MSILInect实现编译时AOP之预览

      在本文之前的前几篇浅谈.NET编译时注入(C#-->IL).浅谈VS编译自定义编译任务-MSBuild Task(csproject).编译时MSIL注入--实践Mono Cecil(1)已经讨论了MSBuild和Mono.Cicel.在这里我们将会利用它来实现一个简单的编译时AOP注入机制(这里所说的编译时是指c#到MSIL的预编译过程).我更倾向于像EL(微软企业库框架)这类动态AOP.编译时AOP有PostSharp这种被称之为静态AOP框架,其优势在于直接代码语句,性能更好,

浅谈.NET编译时注入(C#-->IL)

原文:浅谈.NET编译时注入(C#-->IL)      .NET是一门多语言平台,这是我们所众所周知的,其实现原理在于因为了MSIL(微软中间语言)的一种代码指令平台.所以.NET语言的编译就分为了两部分,从语言到MSIL的编译(我喜欢称为预编译),和运行时的从MSIL到本地指令,即时编译(JIT).JIT编译分为经济编译器和普通编译器,在这里就不多说了,不是本文的重点.本文主要讨论下预编译过程中我们能做的改变编译情况,改变生成的IL,从编译前后看看微软C#3.0一些语法糖,PostSharp

编译时MSIL注入--实践Mono Cecil(1)

   紧接上两篇浅谈.NET编译时注入(C#-->IL)和浅谈VS编译自定义编译任务-MSBuild Task(csproject),在第一篇中我们简单研究了c#语法糖和PostSharp的MSIl注入,紧接第二篇中我们介绍了自定义MSBuild编译任务(记得有位老兄发链接用 MSBuild自动发布Silverlight xap ,我想说的我做的是自定义编译任务,不是什么发布,MSBuild本就是一个发布工具).之所以在此前介绍编译Task是因为我讲介绍的就是利用MSBuild和MSILInje

运行时和编译时元编程—运行时元编程

原文链接   译文链接   译者:JackWang 运行时和编译时元编程 第一部分 Groovy语言支持两种风格的元编程:运行时元编程和编译时元编程.第一种元编程支持在程序运行时修改类模型和程序行为,而第二种发生在编译时.两种元编程有各自的优缺点,在这一章节我们将详细讨论. 注:译者也是第一次接触Groovy,由于时间和水平有限(姑且让译者使用这个理由吧,对待知识本应该一丝不苟)部分专有名词可能翻译不准确甚至有误(读者阅读的过程中最好能参考原文),恳请读者不吝留言指出,谢谢! 1.运行时元编程

运行时和编译时元编程—编译时元编程

原文链接    译文链接     译者:JackWang 运行时和编译时元编程 第二部分 2 编译时元编程 Groovy的编译时元编程支持编译时生成代码.这些变换(译者注:原文该专有名词是transformations,译者直译为变换,也许不准确.如果有知道准确翻译的读者恳请不吝赐教,待译者修正)叫做程序的抽象语法树(AST),在Groovy里,我们叫做AST变换.AST变换支持在编译过程中植入钩子,修改抽象语法树之后继续编译生成正常的字节码流.和运行时元编程相比,这种转换可以在类文件的修改可见

运行时和编译时元编程—运行时元编程(一)

运行时和编译时元编程 第一部分 Groovy语言支持两种风格的元编程:运行时元编程和编译时元编程.第一种元编程支持在程序运行时修改类模型和程序行为,而第二种发生在编译时.两种元编程有各自的优缺点,在这一章节我们将详细讨论. 注:译者也是第一次接触Groovy,由于时间和水平有限(姑且让译者使用这个理由吧,对待知识本应该一丝不苟)部分专有名词可能翻译不准确甚至有误(读者阅读的过程中最好能参考原文),恳请读者不吝留言指出,谢谢! 1.运行时元编程 通过运行时元编程,我们可以推迟运行时的分支决策(译者

c++编译时如何把private属性变成public?

c++编译时如何把private属性变成public? 在做一些已经写好的代码的单元测试的时候,有时候需要使用到类私有的成员方法或变量.我们不想改动原来的代码,但是又能访问这些私有或者受保护的方法,遇到这种情况怎么办? 1.手工替换 在原有代码中将private手工替换成public,将protected手工替换成public. 这种方法是我们最不想用的方法,因为这需要改变原来的代码. 2.宏替换 这种方法比较讨巧,但也很好用,我们可以定义两个宏: #define private public

ndk-Android NDk 怎么编译时动态链接第三方so库,有头文件

问题描述 Android NDk 怎么编译时动态链接第三方so库,有头文件 最近在做一个项目,大神把底层的算法封装成so(普通的c++函数),并给出头文件,我需要先 进行封装,然后给java调用.在我写的C++(符合JNI规范)里面调用so库函数, 下面贴图求解答: 1.项目的目录结构 其中 libvvw.so就是第三方库: Test_vvw.h就是第三方库的头文件 2.java 的native方法定义 3.native的实现方法体 FrameDecode.cpp文件 4.Android.mk文

编译时标签(对JSP进行的XSLT预处理)

js|编译 一篇旧文,翻出来回顾一下.BTW,抗议csdn的分类,XML怎能归于.NET之下!! 发信人: HAX(海曦), 信区: WebDevelop 标 题: 发信站: 饮水思源 (2002年02月12日00:10:32 星期二), 站内信件 编译时标签(对JSP进行的XSLT预处理) 原文:http://www.mail-archive.com/taglibs-dev@jakarta.apache.org/msg00390.html From: James Strachan Subjec