AOP Ninject 停止被调用的拦截方法

Posted

技术标签:

【中文标题】AOP Ninject 停止被调用的拦截方法【英文标题】:AOP Ninject Stop Intercepted Method From Being Called 【发布时间】:2013-10-01 06:29:21 【问题描述】:

我正在使用 Ninject 和 AOP 来做一些缓存。我有一个属性,我可以将其应用于存储库中的任何方法,并且在 BeforeInvoke 上,如果有一个缓存对象,它将返回我的缓存对象,并且 AfterInvoke 创建一个缓存对象。这一切都很好,但我不知道如何停止调用初始方法,即如果有一个缓存的对象,则返回它而不是调用一个被拦截的方法。我的拦截器在这里:

public class CacheInterceptor : SimpleInterceptor

    protected override void BeforeInvoke(IInvocation invocation)
    
        Type returnType = invocation.Request.Method.ReturnType;
        string cacheKey = CacheKeyBuilder.GetCacheKey(invocation, serializer);
        object cachedValue = cache.Get(cacheKey);
        if (cachedValue == null)
        
            invocation.Proceed();
        
        else
        
            object returnValue = serializer.Deserialize(returnType, cachedValue);
            invocation.ReturnValue = returnValue;
            returnedCachedResult = true;
        
     

尽管在 else 语句中我显然不是说调用被调用的方法'invocation.Proceed();'它仍然调用它。如何告诉 ninject 只返回 invocation.ReturnValue ?

【问题讨论】:

你确定你的拦截器被调用了吗?你能在调试器中单步执行吗? 是的,拦截器正在被调用,我可以看到调用。ReturnValue = returnValue;被设置但是它也调用了方法 【参考方案1】:

在这种情况下,您不能使用SimpleInterceptor,因为这是您希望在实际方法调用之前或之后执行操作的最常见场景的基类。另外你不能调用Proceed 而是实现IInterceptor 接口并将你的代码放入Intercept 方法中。

但也许我们应该在未来的版本中扩展SimpleInterceptor,这样你就可以防止调用实际的方法:

public abstract class SimpleInterceptor : IInterceptor

    private bool proceedInvocation = true;

    /// <summary>
    /// Intercepts the specified invocation.
    /// </summary>
    /// <param name="invocation">The invocation to intercept.</param>
    public void Intercept( IInvocation invocation )
    
        BeforeInvoke( invocation );
        if (proceedInvocation)
        
            invocation.Proceed();
            AfterInvoke( invocation );
        
    

    /// <summary>
    /// When called in BeforeInvoke then the invokation in not proceeded anymore.
    /// Or in other words the decorated method and AfterInvoke won't be called anymore.
    /// Make sure you have assigned the return value in case it is not void.
    /// </summary>
    protected void DontProceedInvokation()
    
        this.proceedInvocation = false;
    

    /// <summary>
    /// Takes some action before the invocation proceeds.
    /// </summary>
    /// <param name="invocation">The invocation that is being intercepted.</param>
    protected virtual void BeforeInvoke( IInvocation invocation )
    
    

    /// <summary>
    /// Takes some action after the invocation proceeds.
    /// </summary>
    /// <param name="invocation">The invocation that is being intercepted.</param>
    protected virtual void AfterInvoke( IInvocation invocation )
    
    

【讨论】:

以上是关于AOP Ninject 停止被调用的拦截方法的主要内容,如果未能解决你的问题,请参考以下文章

Ninject Interception Extension (AOP) - 好的工作示例/教程? [关闭]

Spring AOP为啥不能拦截从对象内部调用的方法

Spring AOP不拦截从对象内部调用的方法原因

Spring AOP不拦截从对象内部调用的方法原因

Spring AOP不拦截从对象内部调用的方法

spring aop无法拦截类内部的方法调用