【问题标题】:Aspect Oriented Programing (AOP) solutions for C# (.Net) and their features [closed]C#(.Net)的面向方面编程(AOP)解决方案及其功能[关闭]
【发布时间】:2011-06-27 07:34:02
【问题描述】:

我想在这里询问3个信息:

  1. 没有针对 C# (.Net) 中的面向方面编程 (AOP) 的集成解决方案来自 Microsoft,对吗?是否有任何此类解决方案正在开发或计划中?

  2. 有哪些解决方案允许在 C# (.Net) 中使用面向方面的编程 (AOP)?它们的优点/缺点是什么?我还没有找到任何包含所有可用选项和一些信息的综合列表供我决定使用哪个选项。最接近的是this list

  3. 什么是(在您看来)最佳 AOP 解决方案 C#(.Net) 考虑以下标准:

    1. 它应该类似于 AspectJ 并且具有相似的语法
    2. 使用简单:不需要 XML 配置 - 只需编写一些常规类、一些方面类并编译将它们编织在一起,然后运行。
    3. 应包括 AspectJ 的所有功能。支持泛型。
    4. 解决方案应稳定、广泛使用和维护。
    5. 应该提供二进制文件(因此可以使用)或 C# 源代码的编织。
    6. 用于可视化的 GUI 工具(甚至更好 - VS 插件)是一个优势。

我认为,如果某项满足 3. 中的大部分标准,那么它就是通用解决方案的候选者。如果某些现有解决方案适合我的需求,我找不到任何地方。

【问题讨论】:

  • 我正在考虑提出这个社区 wiki 问题,但我不知道如何 :(
  • @drasto:CW 不再可能,在这种情况下,不可取。
  • 这是如何被选为题外话的?这是完全可以接受的。也许有点主观,但我认为 OP 给出了足够的标准,应该没问题。
  • @Crazy:我认为这对程序员来说是个好问题,而不是 SO。
  • @John 我以前不知道 Programers 网站的存在,但现在我检查了它,我不认为它在错误的地方。人们会在这里提出关于最适合特定软件开发问题的技术的问题。我就是这样做的——我将在我的项目中使用答案(如果.Net 有任何这样的解决方案)。但是我同意它也可以在程序员身上——但答案会更像下面的 James Blank ......我真正想要的只是一个答案:有这个和那个库,其中一个可能适合你需要因为某事*

标签: c# .net aop


【解决方案1】:

正如 Adam Rackis 指出的那样,Post# 是必经之路,它与 .NET 平台上的 AspectJ 非常接近。

主要区别显然是 AspecJ 具有对方面的语言支持,而 Post# 是 .NET 程序集的后编译编织器。 (因此没有语言集成)

但是,Post# 可以使用连接点,例如字段访问、try catch 块、调用和函数(即调用者和被调用者)

  1. 甚至不接近,AspectJ 是一种语言,Post# 可以使用自定义切入点,但最常见的是使用属性来装饰要切入点的方法(eh..grammar?)

  2. 检查

  3. 除了语言支持之外的一切

  4. 检查

  5. 检查 - 这是一个编译后编织器

  6. 有限,weaver 会生成智能感知信息并显示哪些方法受到了影响

如果您想要支持方面的 .NET 语言,请查看http://aspectsharpcomp.sourceforge.net/samples.htm

关于不同的方法,有几种:

  1. Post compile weaving ,这就是 Post# 所做的。 它只是破坏 .NET 程序集并注入方面代码。

  2. 真正的代理/MarshallByRefObject。 基于远程基础设施。 要求您的类从基类继承。 性能极差,没有“自我拦截”

  3. 动态代理。 这是我的旧图书馆 NAspect 使用的。 您使用工厂来创建要应用方面的类型的子类。 子类将使用接口添加混合代码并覆盖虚拟方法并注入拦截器代码。

  4. 源代码编织。 顾名思义,它会在编译之前转换您的源代码。

[编辑] 我忘了把这个添加到列表中:

  1. 接口代理 类似于动态代理,但不是将拦截代码应用于子类,而是将拦截代码添加到运行时生成的接口代理。 也就是说,您得到一个实现给定接口的对象,然后该对象将每个对任何接口方法的调用首先委托给 AOP 拦截代码,然后将调用委托给真实对象。 也就是说,这里有两个对象在起作用,代理和主体(你的真实对象)。

Client -> Interface Proxy -> AOP interception -> Target/Subject

这就是 Spring 所做的 AFAIK。

1) 和 3) 是最常见的。 它们各有利弊:

编译后:

优点:

  • 几乎所有东西都可以点切,静态的、密封的、私有的
  • 仍然可以使用“new”创建对象

缺点:

  • 不能基于上下文应用方面,即如果一个类型受到影响,它将影响整个应用程序。

  • 切入点私有、静态、密封结构可能会导致混乱,因为它违反了基本的 OO 规则。

动态代理:

优点:

  • 上下文相关,一种类型可以根据上下文应用不同的方面。

  • 易于使用,无需配置或构建步骤。

缺点:

  • 切入点有限,只能拦截接口成员和虚拟成员

  • 必须使用工厂来创建对象

【讨论】:

  • +1 这是一个真正帮助我做出决定的答案。
  • 那个 Spring.Net AOP(优点/缺点)怎么样?它属于您的哪个类别?
  • 添加了关于 spring 如何做到这一点的信息。见替代 5
  • “必须使用工厂创建对象”对我来说是最大的问题。
【解决方案2】:

1 - 正确

2 - PostSharp 是一个杰出的 C# AOP 库

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 来可视化这样的方面

【讨论】:

  • 我没有仔细研究过 PostSharp 2.0,但是当我看到它与 AspectJ 相比时,它的功能非常有限。
  • 我不熟悉 AspectJ - 它有什么 PostSharp 没有的功能?
  • 您可能想查看eclipse.org/aspectj/doc/released/progguide/index.html 以了解更多信息,但基本上,我可以拥有一个我没有代码的程序。然后我可以编写将在运行时修改应用程序的代码,以赋予它不同的行为。您也可以在编译时进行这些更改,顺便说一句。因此,我可以拥有一个 C# 类(理论上),并且基于我包含的程序集,它可以是 SOAP 或 REST 服务,或者是 WPF 应用程序的控制器,如果 AspectJ 在 .NET 上工作的话。
  • 您可以拦截对代码的调用,因此也没有 PostSharp 的源代码,出于各种原因,我们经常使用它来拦截对 .NET 运行时的调用。 PostSharp 的一个主要优点是它在编译时完成所有操作,这会导致更长的构建时间,是的,但与在运行时波动的其他 AOP 框架相比,它只会使运行时执行时间延长最少。这就是我们达成交易的原因 + 它对开发人员友好。
  • 3.支持泛型,6. VS 插件也存在,它将突出显示编织的方法/类,并为您提供可点击的超链接到方面
【解决方案3】:

问题在于您正在比较不同的语言并试图将方形钉钉入圆孔中。

对于 Java,AspectJ 满足了语言限制的需求,但 .NET 不一定有这些限制,因为 JVM 没有,但 Java 有。

例如,您可以使用 IronPython 或 IronRuby(以及其他)来编写非常动态的程序集,因此您可以编写一种 DSL(域特定语言),使用户能够添加不是 XML 的代码,但会改变程序的运行方式。

您可以使用 C# 中的扩展方法通过换出程序集来更改行为,因此您有一个程序集具有记录到文件的扩展名,然后您将该程序集换成另一个具有相同命名空间的程序集来发送数据到网络服务,或做一个 noop。

但是,这有一些难以克服的限制,例如能够在每个调用的函数中使用一个方面来做某事,例如使用 cflow (http://www.eclipse.org/aspectj/doc/released/progguide/semantics-pointcuts.html),但这可能是因为我没有'没有足够的思考如何去做。

我的意思不是要对 .NET 如何不需要 AspectJ 给出完整的解释,而是要表明有一些方法可以在不使用 AOP 的情况下获得您可能期望的行为。

对于在 JVM 上运行的应用程序,您可以使用 Groovy、Clojure、JR​​uby 和 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 mangling AOP vs. Runtime Proxy AOP , http://rogeralsing.com/2008/01/08/code-mangling-aop-vs-runtime-proxy-aop/

【讨论】:

  • -1 我完全不同意,你错过了 AOP 的重点。 AOP 是完全不同的编程范式,就像过程式编程和 OO 编程之间的区别一样。它与语言的限制无关。任何可以用 AOP 编写的程序也可以不用它来编写(以及任何用 OOP 编写的程序都可以用过程式编程编写)。 AOP 允许轻松地向现有程序添加新功能(方面),但您也可以使用纯 Java 或 C# 添加它(或者您可以使用扩展方法、IronRuby 和 10 更多...
  • ...技术在一起)。但关键是,使用 AOP,您可以获得结构良好的模块化代码,并且不太喜欢引入错误(编程实践动机 -> 与从过程编程到 OOP 的动机相同)。您可以用 10 种现有技术来替换一个好的 AOP 解决方案,这些技术必须被精简,甚至没有为此目的而改进,但您将把所有东西混合在一起,根本不透明。这适用于使用 AOP 扩展 som 应用程序以及从头开始创建 AOP 应用程序。
  • @drasto - 我花了数年时间使用 AspectJ 来使我的代码更加灵活,但是我对方面所做的工作可以通过其他语言提供的其他方式来完成,因此对它们的需求较少.特定领域的语言允许我们拥有可以在运行时添加到程序中的类型安全代码,在某些语言中,这将为您提供您正在寻找的模块化。
  • 很抱歉,我不同意 IronRuby、扩展方法或其他任何东西可以替代 C# 或任何其他语言的 AOP 语言的建议。 AOP 是(正如我们所同意的)新范式。一种范式,既用于创建不应该具有自适应性的新应用程序(至少具有方面),也用于那些期望随着时间的推移适应新需求的应用程序。顺便说一句,您似乎忽略了第一种情况。与编写程序的任何其他范式一样,它需要实现该范式的优秀编程语言。 IronRuby 结合扩展方法我不知道...
  • ...还有什么不是一种好的编程语言,事实上所有这些技术加在一起根本就不是编程语言。您可以使用它们使您的应用程序易于适应,但这并不意味着它们是 AOP 语言。我在这里的原始问题中要求的是 AOP 编程解决方案,而不是创建自适应应用程序的方法。无论如何,我认为使用 IronRuby 等你不能做你可以用 AOP 做的事情。
猜你喜欢
  • 2010-11-27
  • 2012-09-03
  • 1970-01-01
  • 1970-01-01
  • 2015-04-28
  • 2012-08-14
  • 2020-07-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多