我们提供安全,免费的手游软件下载!
最近在项目中发现了别人使用Rougamo框架,于是我花了一些时间仔细研究了一下,并在这里记录下我的研究成果。
首先,我们先了解什么是Aop? Aop 是指面向切面编程 (Aspect Oriented Programming),而所谓的切面,可以认为是具体拦截的某个业务点。
我们常用的aop框架是 AspectCore,他是属于动态代理,也就是发生在运行时期间对代码进行“修改”。
Rougamo、Fody 是属于静态编织,是指 在编译阶段将代码修改或额外的功能直接嵌入到程序集中,这个过程发生在源代码被编译成可执行文件或库之前。这意味着,一旦编译完成,插入的代码就已经是程 序集的一部分,无需在运行时再进行额外的操作。
Rougamo 是一个开源项目,github: https://github.com/inversionhourglass/Rougamo ,他是通过Fody -> Mono.Cecil 的方式实现静态编织 实现Aop功能。
创建控制台程序,Nuget安装 Rougamo.Fody
运行后会自动创建FodyWeavers.xsd 和 FodyWeavers.xml
下面是运行结果
这时候我们可以看到 增加了LoggingAttribute 特性的方法在运行前、运行成功、运行结束 执行了 OnEntry(MethodContext context) 、OnSuccess(MethodContext context)、OnExit(MethodContext context) 方法,这时我们打开ILSpy工具,看看实际运行的代码
从实际运行的代码我们可以看到,原先Add(int a, int b)方法中的执行内容被移动到 $Rougamo_Add方法中,而Add(int a, int b)方法先是new LoggingAttribute() 和 new Rougamo.Context.MethodContext() -> 执行了 loggingAttribute.OnEntry(methodContext); -> 在do{}while(bool) 执行了$Rougamo_Add(a, b); -> 在 exception 中执行了loggingAttribute.OnException(methodContext); -> 在 finally中执行了 loggingAttribute.OnSuccess(methodContext); 和 loggingAttribute.OnExit(methodContext);
注:do{}while(bool) 执行了$Rougamo_Add(a, b); 是因为 Rougamo 可以实现方法执行失败重试功能
至此我们明白了 Rougamo 实现 Aop功能是通过编译时修改IL代码,往代码增加对应的生命周期代码。那他为什么可以做到呢?其实是借用了Fody -> Mono.Cecil 的方式。
代码如下: https://gitee.com/Karl_Albright/csharp-demo/tree/master/FodyDemo/RougamoDemo
Fody 是一个开源项目,github: https://github.com/Fody/Fody ,相关教程文档在 https://github.com/Fody/Home/tree/master/pages
创建类库,选择netstandard2.0,命名为HelloWorld,Nuget安装 Fody 和 FodyPackaging
注:必须创建 netstandard2.0,因为FodyPackaging的目标是netstandard2.0,
在HelloWorld项目中,我们只放 HWAttribute类,继承于 Attribute。代码如下
再次创建类库,选择netstandard2.0,命名为HelloWorld.Fody,Nuget安装 FodyHelpers,引用HelloWorld类库
在HelloWorld.Fody项目中,我们只放ModuleWeaver类(类名是固定的,详情见Fody文档),继承于 BaseModuleWeaver。代码如下
在代码中,我们遍历了所有类型的所有方法,如果方法标注了 HWAttribute特性,则增加 Console.WriteLine("Hello World."); 代码。
创建控制台应用程序,命名为HelloWorldFodyDemo,添加 HelloWorld 和 HelloWorld.Fody 项目引用,并且手动增加 WeaverFiles标签,目标是HelloWorld.Fody.dll
在控制台中,我们需要一个方法,方法上有 HWAttribute 特性就可以了,代码如下
在控制台项目中,我们还需要 FodyWeavers.xml 和 FodyWeavers.xsd 文件,(我也是从上面Rougamo项目中复制的),内容如下
目前,文件结构如下
代码如下: https://gitee.com/Karl_Albright/csharp-demo/tree/master/FodyDemo
最后运行结果如下,很明显,HWAttribute生效了,我们成功的在Echo()方法前打印了Hello World。
我们再次打开ILSpy工具,得到的结果如图,代码增加了Console.WriteLine("Hello World.");行代码
4. Fody 有很多其他的“插件”,大家可以多试试
AutoProperties.Fody : 这个外接程序为您提供了对自动属性的扩展控制,比如直接访问backing字段或拦截getter和setter。
PropertyChanged.Fody: 将属性通知添加到实现INotifyPropertyChanged的所有类。
InlineIL.Fody: 在编译时注入任意IL代码。
MethodDecorator.Fody: 通过IL重写编译时间装饰器模式。
NullGuard.Fody: 将空参数检查添加到程序集。
ToString.Fody: 给属性生成ToString()方法
Rougamo.Fody: 在编译时生效的AOP组件,类似于PostSharp。
相关资讯
热门资讯