Mono Cecil、PostSharp Core和Microsoft CCI用于实现AOP框架的比较。

16

在能力、易用性、文档、样例、社区/支持、VS集成、已知实现、长期可行性和构建速度方面,哪个自定义AOP框架更好呢?

我会从我所知道的开始(到目前为止我只尝试过PostSharp):

  • Microsoft Common Compiler Infrastructure (CCI):我读过它被用于FxCop、ILMerge、Spec#和Code Contracts。它似乎非常低级,因为即使在使用它修改IL时,它也不会处理分支代码的偏移量错误
  • PostSharp:已经有5年历史了,拥有许多AOP的能力(例如,抽象一些你需要手动处理的IL内容),源代码可用,由一个人开发/维护,但他计划将其作为商业产品推出,有文档但仍有改进空间,构建时间大约需要两倍,如何注入IL内容的样例很少,即将发布2.0版本,承诺有很大的改进。
  • Mono Cecil:由一名开发者编写,是Mono套件的一部分,Reflector有一个名为Reflexil的插件使用了Mono Cecil。
3个回答

7

Microsoft.CCI和Mono.Cecil都是低级别的工具,不会验证生成的程序集。如果代码或程序集结构存在错误,需要花费大量时间才能找到问题的原因。
如果PostSharp的功能足够满足您的需求,我建议使用它。
否则... Mono.Cecil具有更好、更易于理解和使用的对象模型。然而,在我的程序中使用它时出现了一个丑陋的错误(在程序集中保存了对错误方法的引用;我认为这与元数据令牌处理有关)
Microsoft.CCI具有丑陋而过度设计的对象模型,同时缺少许多简单的功能;然而,它比Mono.Cecil更成熟。最终,我放弃了Mono.Cecil,并在我的程序中使用了Microsoft.CCI。


感谢分享您的经验!我认为您可以始终使用PEVerify工具来验证您生成的程序集。我现在正在使用PostSharp,到目前为止,我已经能够做到我想要的一切(您说得对,找到原因可能非常令人沮丧...)。您所说的“更成熟”是什么意思?更少的错误?您不使用PostSharp的特定原因是什么?出于好奇,您的程序在做什么? - user65199
我的程序是汇编代码合并/缩减工具,因此 PostSharp 对我没有帮助。我发现 Microsoft.CCI 的错误较少,而且它支持更多的 CLI 功能(例如混合程序集)。然而,它的对象模型使用起来真的很困难。 我使用 PEVerify 来检查生成的程序集(不确定如果没有它我能否成功 :)),但是错误经常会破坏程序集生成过程,并且在这种情况下 PEVerify 是无用的。 - skevar7

3

对于已经存在的大多数框架,我建议您在实现自己的AOP框架时不要这样做。已经有一些框架可用,包括(即将)商业支持的PostSharp和由Typemock支持的AOP框架CThru

但是无论如何,我发现Mono.Cecil非常易于使用。它很好地抽象了Reflection.Emit的需要,并得到了Mono社区的支持。

我建议您看看LinFu - 这是一组开源库,其中一个是基于Mono.Cecil实现的AOP框架。CodeProject上有一篇关于LinFu AOP的不错文章。


我只对在编译时注入代码的AOP感兴趣。 - user65199
LinFu可以做到这一点。它具有一个后编译器任务,用于编织IL。 - Igal Tabachnik
1
虽然LinFu.AOP通过后编译任务编织修改类型的IL以实现代码注入,但实际的代码注入是在运行时进行的,这会导致性能下降。 - user65199

3
据我所知,LinFu是基于Mono.Cecil构建的。
我认为PostSharp.Core比其他框架具有更高级别的特性,因此对于大型项目来说使用起来更容易。你也可以在低层次上工作,但不能在二进制层面上工作(出于设计考虑)。你可以使用PostSharp进行程序集合并/缩小,但它编译回来使用ILASM会有一些限制(例如即使是内部成员也应该命名)。另一方面,将ILASM作为后端使得在PostSharp的顶部开发变得更加容易,因为ILASM验证了许多规则,你可以轻松地阅读生成的MSIL代码。PostSharp甚至允许你在MSIL中放置注释以帮助调试代码生成。
另一个要点:如果你想做一个自定义切面(例如,你开发了一个数据库引擎并想提供一个持久化切面),你需要的不仅仅是一个MSIL重写器。你需要一个AO基础设施来为你完成大部分工作。当你开发自定义切面时,我会说1%的工作是针对你的自定义切面,39%是切面基础设施,60%是MSIL重写器。我经常能够根据PostSharp在几个小时内编写一个非常具体的切面。
所以,回到你的问题,当然带有我的偏见,我会说:如果你想编写混淆器、合并/缩小等,最好选择Mono.Cecil或Microsoft.CCI,因为它们的许可证更友好。但如果只是想开发自定义切面,使用PostSharp将使你节省数周时间,并且如果你计划重新分发PostSharp,我们可以提供令人惊讶的商业条件。

好的,我想我会继续使用PostSharp,因为到目前为止我一直很满意它的表现。 - user65199

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接