我是面向方面编程思想的新手,但我想探索在我的项目中使用它来处理日志记录、报告等的想法。为此,我有一些问题:
- 为了这些有限的目的,我是否应该费心探索这条 AOP 路径?
- 有哪些支持 AOP 的 .NET Framework 可用?
- 这些框架中的哪一个支持流畅的界面(我讨厌 XML 配置):)
Aspect Oriented Programming不仅仅是记录、报告等,如果您查看 PostSharp 的网站,您就会看到。就我个人而言,我没有做太多静态 IL 编织,主要是动态 IL 生成来创建 AOP 拦截器,这样做时我主要使用它来包装和拦截来自控制容器反转的解析。
AOP可以改进异常处理,改进跟踪,改进事务拦截。
例如, NHibernate有一种 AOP,尽管它在编译时是静态的,就简单的事件处理程序而言;但是对于引擎中的某些事件,您可以附加拦截器(又名方面,事件是切入点等)——我使用它来注入,使用 IoC 业务实体到我的域对象中。
强大的 AOP 框架允许您进行泛化,甚至更强大的允许您在运行时进行无开销的泛化;原则上,您有几种不同的方法:
(0)。(不是真的)“预处理器”AOP 又名 C++ 中的模板,ifdefs 等
事务中的用法 查看Castle.Facilities.AutomaticTransactionManagement.TransactionFacility,了解使用 AOP 和 DynamicProxy2 的拦截能力处理事务的好方法。与 System.Transcations 和 System.EnterpriseServices 集成的事务工具是您使用分布式事务协调器(COM 组件)来管理事务。此外,还有多个 p/invoke 进入内核的示例来处理Vista 内核(又名 Server 2008)的 TxF 和 TxR 组件,它们允许您在 NTFS 和注册表上使用事务,从而确保您的 CRUD做的是 ACID,它也很好地与 System.Transactions 集成以创建嵌套事务。
不变验证中的用法 您还可以通过将一些属性附加到参数来将它们用于合同设计。
public void PerformOperation([NotNull, NotEmpty] string value) {
// use string
[NotNull] return new string(' ', 5); // can return with attributes as well
}
目前的问题是附加此元数据并在运行时检查它的开销。但是,您可以指定仅在使用 DEBUG 编译时应用约束检查方面,然后此元数据不会导致性能大幅下降。
如果您正在寻找公理证明,请查看 Sing#/Spec#,因为它更正式,并且工作由编译器完成。
要注意的事情要注意的 最重要的一点是,如果一个问题,即在您的方法之前或之后运行的某些代码正在改变控制流,可能会返回意外类型,返回过早或一般情况下不符合您调用的方法的意图,您可能会遇到难以调试的错误。
此外,请注意从属性中抛出异常,因为您永远不知道何时或从哪个程序集发生反射;对您的属性的反映可能不会在您期望的时候发生。当我在属性中附加类型并仔细检查它们时,这发生在我自己身上。
还要注意这样一个事实,即您在添加全局“切入点”时打开了一个可能的攻击向量,如果有人可以访问该切入点,可以用来重定向系统的大部分。
其他框架 如果您有兴趣了解更多关于 AOP 的一般知识,我建议您查看 Rickard Öberg 在Qi4J上的演示文稿,它是 Java 中用于 AOP 的一个非常好的框架(尽管 java 具有稍微不同的对象继承语义,但这使得我们有点难以理解在 C#/F#/Nermle/Boo 中使用。
AOP + 插件 将面向方面编程与运行时生成的程序集(例如 dynamicproxy2 创建的程序集)一起使用的另一个有趣的可能性是,您还可以使用它们来包装跨应用程序边界的对象,从而简化插件管道的创建。我曾暗自希望微软在为 3.5 创建 AddIn 框架时使用它,但不幸的是,他们选择采用静态代码生成方式,为开发人员创建加载项带来了相当大的开销。问题是,除非卸载完整的 AppDomain,否则无法再次卸载为“不仅仅是反射”加载到 AppDomain 中的类型,
使用 AOP 进行全局垃圾回收......在公共语言基础架构上运行在 linux/windows 上的分布式系统中。这篇论文有点难下载,所以我把它上传到我的服务器上,这样我就知道它在哪里了。
Post Scriptum (如果您在 CLR 上使用非标准语言而不是 DLR IL-weaving 可能会创建不符合标准的代码。我认为对于 F# 尤其有趣,因为使用大量非标准代码非常棒语言的好处(元组说)——如果你想获得编译时警告,你可以用 [assembly: CLSCompliant] 标记你的程序集。)
我不能说 .NET 的细节,但是 AOP 和能够将钩子附加到任意方法的更一般的想法是一种方便的技术,可以解决一些其他棘手的问题。
一个例子是按合同设计。假设您有一堆方法,您想在这些方法上应用一些常见的合同。您可以在调用每个方法之前和之后添加一些“建议”(AOP 术语),而无需将其剪切并粘贴到每个方法中。
在测试时,了解某些内部方法中发生了什么通常很有用。它被调用了多少次,也许它返回了什么。您可以添加一个方面来执行该监视,而无需将分散注意力的测试代码添加到方法本身。甚至可能无法编辑该方法的代码。
只需注意方面是如何实现的。一些实现是精心制作的预处理器,可能会使调试代码更加复杂。其他人则顺利地融入了语言。动态语言很好地处理 AOP。Perl 有用于 AOP 的Aspect.pm和更通用的Hook::LexWrap来完成方法挂钩。
AOP 对我来说也很有趣。在我看来,日志记录和性能监控、报告是 AOP 旨在处理的内容。对于 .NET,Post Sharp是一个非常好的 AOP 框架。
我只对它进行了一点试验,但它似乎实现得很好。
如果您要查看 Post Sharp,您可以从 CodePlex 下载 Google Book Downloader。我认为这个项目使用它。
不要认为它完全不同。AOP 通过减少耦合、增加内聚力、通过赋予特定类型 1 单一职责的对象来分离关注点来改进(IMO)您的设计。如果您来自 .net 世界 PostSharp 使用自定义属性来编织建议。如果您来自 Java 世界,您可以使用名为AspectJ的 Java 扩展。AOP 的应用程序比您通常看到的要多。