2

我正在使用 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 ?

4

1 回答 1

5

您不能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 )
    {
    }
}
于 2013-09-26T23:35:26.800 回答