C#属性和Aop范例

Med*_*uil 2 c# aop

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

Jam*_*son 5

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

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

https://www.postsharp.net/aop.net/msil-injection

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

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

例如,您有一个方法:

public int Add(int x, int y)
{
     return x + y;
}
Run Code Online (Sandbox Code Playgroud)

并且您希望通过手动添加此代码来为此方法提供日志记录或诊断(日志是假设的日志记录API):

public int Add(int x, int y)
{
     log.Enter("Add", x, y);
     log.Leave("Add", x, y);
     return x + y;
}
Run Code Online (Sandbox Code Playgroud)

你分散了方法的目的,在考虑方法复杂性和单一责任原则时开始混淆水.

理想情况下,您希望能够在运行时/编译时添加此行为,并且通常对于多个方法,这将成为一个跨领域的问题,例如,您希望记录所有内容.

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

[Log]
public int Add(int x, int y)
{
    return x + y;
}
Run Code Online (Sandbox Code Playgroud)

我们已经将元数据添加到Add方法([Log] Attribute)以指示我们想要记录此方法(并且还原为不违反单一责任原则的方法),但是该属性本身相对没有意义.

需要的是解释自定义属性并提供拦截方法调用并添加log.Enter,log.Leave调用的机制.这是我们选择PostSharp或动态代理或其他AOP框架的地方.