C#属性与Aop范式

C#属性与Aop范式,c#,aop,C#,Aop,我想知道使用C#自定义属性和AOP框架(如PostSharp)之间的区别。 如何在它们之间进行选择?自定义属性是在代码元素上声明元数据的一种方法,系统的其他元素可以理解这些元数据,包括编译器、AOP框架、验证引擎等 PostSharp执行IL(中间语言)编织,例如在编译后,它根据配置/属性在程序集中的某些点注入IL。例如,您可以向方法添加自定义属性,并且在编译期间,PostSharp将编写IL来拦截此方法,并在运行时为您提供行为 PostSharp是实现AOP的一种方法,还有许多其他方法,包括

我想知道使用C#自定义属性和AOP框架(如PostSharp)之间的区别。
如何在它们之间进行选择?

自定义属性是在代码元素上声明元数据的一种方法,系统的其他元素可以理解这些元数据,包括编译器、AOP框架、验证引擎等

PostSharp执行IL(中间语言)编织,例如在编译后,它根据配置/属性在程序集中的某些点注入IL。例如,您可以向方法添加自定义属性,并且在编译期间,PostSharp将编写IL来拦截此方法,并在运行时为您提供行为

PostSharp是实现AOP的一种方法,还有许多其他方法,包括动态代理(例如Castle.Core),它可以通过提供希望扩展的类的动态子类在运行时拦截方法

在这两个示例中,属性可以为您提供配置这些功能行为的方法

例如,您有一个方法:

public int Add(int x, int y)
{
     return x + y;
}
您希望通过手动添加此代码为该方法提供日志记录或诊断(日志是一个假设的日志记录API):

当考虑到方法的复杂性和单一责任原则时,你会偏离方法的目的,并开始弄脏水

理想情况下,您希望能够在运行时/编译时添加此行为,通常对于多个方法,这将成为一个横切关注点,例如您希望记录所有内容

因此,您最终需要一种方法来通知系统您希望将日志记录应用于Add方法。一种方便的方法是使用属性标记方法:

[Log]
public int Add(int x, int y)
{
    return x + y;
}
我们已经将元数据添加到Add方法([Log]属性)中,以表明我们希望记录此方法(并恢复为不违反单一责任原则的方法),但是该属性本身相对来说没有意义


需要的是解释自定义属性并提供拦截方法调用和添加log.Enter、log.Leave调用的机制。这就是我们选择PostSharp或Dynamic proxies或其他AOP框架的地方。

AOP是一种编程范例,而属性是C#(或使用它们的任何其他语言)的实现细节。它们在两个不同的尺度上。实现AOP的一种方法是使用属性,但AOP是一个更广泛的概念。答案很好。我是否可以建议将“自定义属性是声明的方式…”一段移到答案的开头?这才是问题的症结所在——属性可以用于各种各样的事情,但它们自己却不能做任何事情。AOP框架使用这些属性来实际执行任务。postsharp不是免费的
[Log]
public int Add(int x, int y)
{
    return x + y;
}