针对C#(.Net)的面向方面编程(AOP)解决方案及其特性
我想在这里要求3个信息:
Microsoft在C#(.Net)中没有面向方面编程(AOP)的集成解决方案是否正确? 有没有这样的解决方案正在开发或计划中?
有哪些解决方案允许在C#(.Net)中使用面向方面编程(AOP)? 他们有什么优点/缺点 ? 我还没有找到任何包含所有可替换选项和一些信息的综合列表,以供我决定使用哪一个。 这个列表最接近。
考虑到以下标准, (在您看来)什么是(您认为) 最 适合C#(.Net)的 AOP解决方案:
我认为,如果满足3中的大部分标准,那么它就是一个常用解决方案的候选人。 如果现有的一些解决方案符合我的需求,我就无法找到任何地方。
正如Adam Rackis指出的那样,Post#是要走的路,与.NET平台上的AspectJ差不多。
主要的区别很明显,AspecJ对方面有语言支持,而Post#是.NET程序集的后编译编织器。 (因此没有语言整合)
但是,Post#可以使用连接点,例如字段访问,尝试catch块,调用和函数(即调用者和被调用者)
没有关闭,AspectJ是一种语言,Post#可以使用自定义切入点,但最常见的是使用属性来修饰要切入的方法(eh..grammar?)
查
一切只是语言支持
查
检查 - 这是一个后编译织布工
编织器将生成智能感知信息并显示哪些方法已受到影响
如果您想要支持方面的.NET语言,请查看http://aspectsharpcomp.sourceforge.net/samples.htm
关于不同的方法,有几个:
Post编译后,这是Post#的功能。 它只是破坏.NET程序集并注入方面代码。
真正的代理/ MarshallByRefObject。 基于远程处理基础设施。 需要您的类从基类继承。 表现极差,没有“自我拦截”
动态代理。 这是我旧图书馆NAspect使用的。 您使用工厂来创建要应用方面的类型的子类。 子类将使用接口添加混合代码并覆盖虚拟方法并注入拦截器代码。
源代码编织。 顾名思义,它会在编译之前转换您的源代码。
[编辑]我忘了将这一个添加到列表中:
Client -> Interface Proxy -> AOP interception -> Target/Subject
这是春天做的AFAIK。
1)和3)是最常见的。 他们都有优点和缺点:
后编辑:
优点:
缺点:
无法应用基于上下文的方面,也就是说,如果某个类型受到影响,它将受到整个应用程序的影响。
切断私人,静态,密封的构造可能导致混乱,因为它破坏了基本的OO规则。
动态代理:
优点:
在上下文中,一个类型可以根据上下文应用不同的方面。
易于使用,无需配置或构建步骤。
缺点:
有限的切入点,只有接口成员和虚拟成员可以被拦截
必须使用工厂来创建对象
1 - 正确
2 - PostSharp是一个优秀的AOP库,适用于C#
3 - 我不知道AspectJ是如何工作的,但是使用PostSharp,你只需将你的方面定义为属性,然后用上述属性修饰你的方法。
下面是一个使用try catch封装方法调用的方面示例,并记录了所有抛出的异常:
[Serializable]
public class ErrorAspectAttribute : OnMethodBoundaryAspect {
private bool Notify;
public ErrorAspectAttribute(bool notifyUser = true) {
this.Notify = notifyUser;
}
public override void OnException(MethodExecutionEventArgs args) {
ErrorLoggerUtil.LogException(args.Exception);
if (Notify)
MessageBox.Show("An error has occurred. Please save blah blah blah", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
args.FlowBehavior = FlowBehavior.Return;
}
}
所以逐点
1 - 我不知道
2 - 检查
3 - 我不知道4 - 支票
5 - 检查(很确定)
6 - 不 - 不知道如何使用GUI来显示这样的方面
问题在于你正在比较不同的语言,并试图强制方块钉入圆孔。
对于Java AspectJ由于语言限制而满足需求,但.NET并不一定具有这些限制,因为JVM没有,但Java确实有此限制。
例如,您可以使用IronPython或IronRuby(除其他外)编写非常动态的程序集,以便您可以编写一个DSL(特定于域的语言),使用户可以添加不是XML的代码,但会改变程序的运行方式。
您可以使用C#中的扩展方法通过换出程序集来更改行为,因此您有一个程序集具有可以登录到文件的扩展,然后将该程序集换成另一个具有相同名称空间的程序集,以便将数据发送到Web服务,或者做一个noop。
但是,这样的限制很难克服,比如能够使用一个方面在每个被调用的函数中执行某些操作,例如使用cflow(http://www.eclipse.org/aspectj/doc/released /progguide/semantics-pointcuts.html),但这可能是因为我没有足够考虑如何去做。
我的观点并不是完全解释.NET如何不需要AspectJ,而是为了表明不使用AOP就可以获得您期望的行为。
对于运行在JVM上的应用程序,例如,可以使用Groovy,Clojure,JRuby和Scala来解决Java的局限性。
更新:
我希望能够缩短我的答案,但对AOP的一些了解可能对我的答案增加上下文很有帮助。
面向方面编程(AOP)是一种不同的编程范例,用于切入类的功能,例如日志记录。 日志记录是一种常见的情况,您可能希望记录所有正在使用的SQL查询,因此,不是将代码从一个地方复制到另一个地方,而是将它放在一个地方,然后放到您指定的任何位置,因此,如果您稍后决定要更改日志记录的位置,请在一个位置更改它。
但使用AspectJ有更多的选择。 例如,您销售一个存储密码的程序。 A公司使用IDEA,B公司使用AES。 为了适应你改变在运行时使用的代码,所以你不必冒险重新编译代码和引入新的错误,并且它被改变了,所以每当有人调用getPassword()
,新代码就被用来解密它。
您还可以将功能添加到现有类中,以便将方法放入接口中,以便使用该接口的所有内容现在都可以访问这些函数,因此方法现在在接口中是具体的。
但是,通过使用.NET和JVM上的其他语言,您可以通过仔细选择要使用的语言来使用相同的模块化来完成所有这些操作。 例如,在Java中,您可以访问用Groovy或Scala编写的类,这样您就可以在这些语言中获得更多灵活性,并且仍然拥有Java中的主要应用程序。
在C#中,您可以使用F#,IronPython或IronRuby来获得此功能,或者在某些情况下,您可以使用C#。
因此,面向方面编程的需求因为这些虚拟机上可用的动态或强类型函数语言而减少,但是,您通过使用多语言解决方案来交易复杂性方面的工作。
有关AOP的更多信息,IBM有一些关于使用AOP @ Work系列的令人难以置信的文章:http://www.ibm.com/developerworks/views/java/libraryview.jsp?search_by=AOP@work:
有关.NET上的AOP的一些想法,您可以阅读Code AOP与运行时代理AOP的代码,http://rogeralsing.com/2008/01/08/code-mangling-aop-vs-runtime-proxy-aop/
链接地址: http://www.djcxy.com/p/95169.html上一篇: Aspect Oriented Programing (AOP) solutions for C# (.Net) and their features