我正在使用Ninject和AOP来做一些缓存。 我有一个属性,我可以将其应用于存储库中的任何方法,并且在 BeforeInvoke 上,如果有,它将返回我的缓存对象,并且 AfterInvoke 创建一个缓存对象。 这一切都很好用,但我无法弄清楚如何阻止调用初始方法,即如果有一个缓存的对象,则返回而不是调用 intyercepted 方法。 我的拦截器在这里:
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 语句中,我显然不是说将调用的方法称为"调用"。继续();'它仍然调用它。 我如何告诉 ninject 只返回调用。返回值 ?
使用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 )
{
}
}