c#和AOP - AOPAlliance(面向方面编程)是如何工作的

本文关键字:何工作 工作 编程 方面 AOP AOPAlliance | 更新日期: 2023-09-27 18:06:46

我刚刚有了一个非常有趣的使用c#的AOP的经验。我有一个返回类型为List的函数,它被拦截了,这一切都很好。然而,拦截器函数是一个验证器样式的函数,可以通过调用并返回布尔值false来阻止真正的函数。

代码看起来有点像这样:

List<Update> updates = Manager.ValidateAndCreate();
// protected void Save(List<Update> updates) { ....
Save(updates);

方法拦截器如下所示

public class ExceptionAdvice : AopAlliance.Intercept.IMethodInterceptor {
    public object Invoke(AopAlliance.Intercept.IMethodInvocation invocation) {
        if (isValid(invocation)) {
            return invocation.Proceed();
        } else {
            return false;
        }
    }
    private bool isValid( ...
 }

现在验证失败后,更新的值实际上是一个布尔值,而不是一个列表,我认为这里会有某种运行时错误,但没有,所以:

updates.GetType().Name == "Boolean"

但:

updates is bool == false

所以save仍然会接受它的更新列表,并会在稍后你尝试使用它时抱怨。

那么这在c#这样的类型安全语言中是如何实现的呢?顺便说一下,它是spring-aop。

编辑:这也可以编译,它确实工作,我已经通过它几次了。

c#和AOP - AOPAlliance(面向方面编程)是如何工作的

我相信这是可能的,因为Spring。Net在运行时发出代理类,跳过编译时类型检查。

它本质上实现了一个封装原始类并动态生成新方法实现的装饰器模式。在动态生成的代理方法中,可以在写IL时更改返回类型,. net允许这样做,因为它不会在运行时检查类型。当然,在编译时它仍然是完全有效的。这就导致了上面那个相当奇怪的场景,即静态类型实际上与运行时类型不同。

下面是true,因为它检查的是实际的运行时类型,在某些情况下可以解析为布尔值。

updates.GetType().Name == "Boolean"

但是下面的语句失败了,因为它将变量的静态类型与布尔类型进行比较,而它不是布尔类型。

updates is bool == false
我建议您不要更改Invoke的类型。