MSBuild + MSILInect实现编译时AOP-改变前后对比
实现静态AOP,就需要我们在预编译时期,修改IL实现对代码逻辑的修改。Mono.Cecil就是一个很好的IL解析和注入框架,参见编译时MSIL注入--实践Mono Cecil(1)。
我的思路为:在编译时将加有继承制MethodInterceptBaseAttribute标签的原方法,重新组装成一个方法(并加上[CompilerGenerated]标签),在加入横切注入接口前后代码,调用此方法。
比如代码:
![复制代码](http://common.cnblogs.com/images/copycode.gif)
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
}
![复制代码](http://common.cnblogs.com/images/copycode.gif)
将会转化(实际注入IL,这里反编译为了c#代码,更清晰)为:
从这里你就会清晰的明白这里实现静态注入了机制和原理了。我们需要做的目的就是从IL出发改变原来代码逻辑,注入我们的截取代码。使用Mono.Cecil具体代码在程序包MethodILInjectTask中。
MatchedMethodInterceptBase是应用于class上匹配该class多个methodattribute基类。rule为匹配规则。
[TestAOP2Attribute(Rule = "TestMethod1*")]public class Class1
这里需要对于继承制该基类的标示class的所有满足rule的方法进行注入。
PropertyInterceptBase:属性注入,Action属性标识get,set方法。
![复制代码](http://common.cnblogs.com/images/copycode.gif)
public int TestProperty
{
get;
set;
}
![复制代码](http://common.cnblogs.com/images/copycode.gif)
属性注入找出标示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注入)
附带:源码下载
使用基于Roslyn的编译时AOP框架 介绍如何通过使用基于Roslyn的编译时AOP框架来解决.NET项目的代码复用问题。 可以在项目编译时自动插入指定代码,从而避免在运行时带来的性能消耗。
visual studio编写C#代码时“未能从程序集.....中加载类型”和“找不到方法”的一种可能的解决办法 编译前报错:$exception { 未能从程序集 XSW.MySQLDAL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null 中加载类型 XSW.MySQLDAL.EnterpriseLibraryProductDAL 。
相关文章
- 基于SpringBoot使用AOP技术实现操作日志管理[通俗易懂]
- Spring AOP 切面@Around注解的具体使用
- 简述SpringAOP的实现原理_spring AOP
- aop计时,超时输出日志
- 【04】Spring源码-手写篇-手写AOP实现(下)
- Spring(三)-AOP
- Spring 初识Aop JDK动态代理实现 原理初显
- .net core实现aop_redis实时计算
- springioc和aop原理_描述spring框架的工作原理
- VB.NET 实现类似JAVA的AOP切面编程,实现菜单权限控制
- AOP拦截实现日志统一打印
- Spring AOP详解
- Spring AOP原理分析
- 理论:第二章:Spring的AOP和IOC是什么?使用场景有哪些?Spring事务与数据库事务,传播行为,数据库隔离级别
- 【字节码插桩】AOP 技术 ( “字节码插桩“ 技术简介 | AspectJ 插桩工具 | ASM 插桩工具 )
- 【GoF 23 概念理解】AOP面向切面编程
- 分布式锁+AOP实现缓存
- 教你如何使用 Redis+AOP+自定义注解实现限流
- Spring Aop 源码实现原理分析详解编程语言
- Spring Aop实现机制分析原理详解编程语言
- springboot aop来实现读写分离和事物配置详解编程语言
- Spring详解(六)——AspectJ 实现AOP编程语言
- Spring里的aop实现方式和源码分析详解编程语言
- Spring AOP(面向切面编程)是什么?
- 基于AOP和HashMap原理学习,开发Mysql分库分表路由组件!