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

简介:

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

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

比如代码


 
 
  1. :[TestAOPAttribute(Order = 1)]  
  2.  
  3. public Class1 TestMethod1(int i, int j, Class1 c)   
  4.         {   
  5.             Console.WriteLine("ok");   
  6.             return new Class1();   
  7.         }  
  8.  
  9. public class TestAOPAttribute : Green.AOP.MethodInterceptBase   
  10.     {   
  11.  
  12.         #region IMethodInject Members   
  13.  
  14.         public override bool Executeing(Green.AOP.MethodExecutionEventArgs args)   
  15.         {   
  16.             Console.WriteLine(this.GetType() + ":" + "Executeing");   
  17.             return true;   
  18.         }   
  19.  
  20.         public override Green.AOP.ExceptionStrategy Exceptioned(Green.AOP.MethodExecutionEventArgs args)   
  21.         {   
  22.             Console.WriteLine(this.GetType() + ":" + "Exceptioned");   
  23.             return Green.AOP.ExceptionStrategy.Handle;   
  24.         }   
  25.  
  26.         public override void ExecuteSuccess(Green.AOP.MethodExecutionEventArgs args)   
  27.         {   
  28.             Console.WriteLine(this.GetType() + ":" + "ExecuteSuccess");   
  29.         }   
  30.  
  31.         #endregion   
  32.  
  33.         #region IMethodInject Members   
  34.  
  35.                #endregion   

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

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

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

 

 
 
  1. [TestAOP2Attribute(Rule = "TestMethod1*")]  
  2.  
  3. public class Class1   
  4.     

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

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

[

 
 
  1. TestAOPPropertyGetAttribute(Action = PropertyInterceptAction.Get)]   
  2.        public int TestProperty   
  3.        {   
  4.            get;   
  5.            set;   
  6.        } 

 

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

   附带:源码下载






 本文转自 破狼 51CTO博客,原文链接:http://blog.51cto.com/whitewolfblog/835177,如需转载请自行联系原作者


相关文章
|
XML 开发框架 Java
《Spring6核心源码解析》已完结,涵盖IOC容器、AOP切面、AOT预编译、SpringMVC,面试杠杠的!
全网首个全面解析Spring6核心源码的专栏,涵盖:IOC容器、AOP切面、声明式事务、AOT预编译和SpringMVC,让你从根本上彻底掌握Spring6核心技术。
535 1
《Spring6核心源码解析》已完结,涵盖IOC容器、AOP切面、AOT预编译、SpringMVC,面试杠杠的!
|
数据可视化 C# C++
使用基于Roslyn的编译时AOP框架
介绍如何通过使用基于Roslyn的编译时AOP框架来解决.NET项目的代码复用问题。 可以在项目编译时自动插入指定代码,从而避免在运行时带来的性能消耗。
362 0
使用基于Roslyn的编译时AOP框架
|
XML Java Android开发
【字节码插桩】Android 打包流程 | Android 中的字节码操作方式 | AOP 面向切面编程 | APT 编译时技术
【字节码插桩】Android 打包流程 | Android 中的字节码操作方式 | AOP 面向切面编程 | APT 编译时技术
248 0
【字节码插桩】Android 打包流程 | Android 中的字节码操作方式 | AOP 面向切面编程 | APT 编译时技术
|
3月前
Micronaut AOP与代理机制:实现应用功能增强,无需侵入式编程的秘诀
AOP(面向切面编程)能够帮助我们在不修改现有代码的前提下,为应用程序添加新的功能或行为。Micronaut框架中的AOP模块通过动态代理机制实现了这一目标。AOP将横切关注点(如日志记录、事务管理等)从业务逻辑中分离出来,提高模块化程度。在Micronaut中,带有特定注解的类会在启动时生成代理对象,在运行时拦截方法调用并执行额外逻辑。例如,可以通过创建切面类并在目标类上添加注解来记录方法调用信息,从而在不侵入原有代码的情况下增强应用功能,提高代码的可维护性和可扩展性。
81 1
|
1月前
|
安全 Java 编译器
什么是AOP面向切面编程?怎么简单理解?
本文介绍了面向切面编程(AOP)的基本概念和原理,解释了如何通过分离横切关注点(如日志、事务管理等)来增强代码的模块化和可维护性。AOP的核心概念包括切面、连接点、切入点、通知和织入。文章还提供了一个使用Spring AOP的简单示例,展示了如何定义和应用切面。
145 1
什么是AOP面向切面编程?怎么简单理解?
|
1月前
|
XML Java 开发者
论面向方面的编程技术及其应用(AOP)
【11月更文挑战第2天】随着软件系统的规模和复杂度不断增加,传统的面向过程编程和面向对象编程(OOP)在应对横切关注点(如日志记录、事务管理、安全性检查等)时显得力不从心。面向方面的编程(Aspect-Oriented Programming,简称AOP)作为一种新的编程范式,通过将横切关注点与业务逻辑分离,提高了代码的可维护性、可重用性和可读性。本文首先概述了AOP的基本概念和技术原理,然后结合一个实际项目,详细阐述了在项目实践中使用AOP技术开发的具体步骤,最后分析了使用AOP的原因、开发过程中存在的问题及所使用的技术带来的实际应用效果。
68 5
|
3月前
Micronaut AOP与代理机制:实现应用功能增强,无需侵入式编程的秘诀
【9月更文挑战第9天】AOP(面向切面编程)通过分离横切关注点提高模块化程度,如日志记录、事务管理等。Micronaut AOP基于动态代理机制,在应用启动时为带有特定注解的类生成代理对象,实现在运行时拦截方法调用并执行额外逻辑。通过简单示例展示了如何在不修改 `CalculatorService` 类的情况下记录 `add` 方法的参数和结果,仅需添加 `@Loggable` 注解即可。这不仅提高了代码的可维护性和可扩展性,还降低了引入新错误的风险。
54 13
|
2月前
|
Java 容器
AOP面向切面编程
AOP面向切面编程
48 0