我有一个使用Ninject 3.0注入的服务类。我已经设置好它的代理是类代理而不是接口代理。该服务有两种方法,第一种方法返回广泛的结果,第二种方法调用第一种方法并对其进行过滤。我添加了一个拦截器来缓存第一个方法的结果。
当我从服务外部调用第一个方法时,拦截工作正常。
问题是,当拦截器调用第二个方法时,它会通过服务本身调用它,而不是通过代理调用它,导致我对我的服务中第一个方法的调用没有被截获,因此没有被缓存。
我怎样才能让它发挥作用?
更新:添加了示例代码
这是我的头脑,很抱歉,如果有什么似乎没有编译
以下是服务类
的示例public class Service : IService
{
[CacheMethodOutput]
public virtual object[] GetObjects(int x)
{
...
}
public virtual object GetObject(int x, int y)
{
return GetObjects(x).SingleOrDefault(o => o.y == y);
}
}
CacheMethodOutputAttribute是一个简单的属性类
这是一个示例绑定(这是我确保拥有类代理而不是接口代理但实际上通过接口保留注入引用的方式)
// Binds by type instead of proxy to create a class proxy
Bind<Service>().ToSelf().InSingletonScope().Intercept().With<CacheAttributeInterceptor>()
Bind<IService>().ToMethod<Service>(r => r.Kernel.Get<Service>());
因此,当我从注入了IService的任何类中调用GetObjects时,拦截器被触发,但它不是从服务本身的GetObject方法触发的。
CacheAttributeInterceptor看起来像这样(但实现细节无关紧要):
public class CacheAttributeInterceptor : SimpleInterceptor
{
public ICacheManager CacheManager {get;set;}
public override void BeforeInvoke(IInvocation invocation)
{
if (Attributes.GetCustomAttribute(invocation.Request.Method, typeof(CacheMethodOutputAttribute) != null)
{
string key = GenerateKey(invocation.Request.Method.Name, invocation.Request.Method.Arguments);
object returnValue;
if (!CacheManager.TryGet(key, out returnValue))
{
invocation.Proceed();
returnValue = invocation.ReturnValue;
CacheManager.Add(key, returnValue);
}
else
invocation.ReturnValue = returnValue;
}
else
base.BeforeInvoke(invocation);
}
}
答案 0 :(得分:-1)
我找到了问题的解决方案/更多细节。
如果我删除GetObject方法上的虚拟修饰符,它将不再被截获,当它将调用GetObjects时,incerceptor将触发。
这一切让我想到如果我想要拦截这两种方法,我需要让拦截器深入工作,如果这是可能的话。