【问题标题】:Ninject Interception: Service calling intercepted method not being intercepted when called within itselfNinject拦截:服务调用被拦截的方法在自身内部调用时未被拦截
【发布时间】:2012-11-04 13:10:56
【问题描述】:

我有一个使用 Ninject 3.0 注入的服务类。我已经设置了它,所以它的代理是类代理而不是接口代理。该服务有 2 种方法,第一种方法返回广泛的结果,第二种方法调用第一种方法并对其进行过滤。我添加了一个拦截器来缓存第一种方法的结果。

当我从服务外部调用第一个方法时,拦截工作正常。

问题是拦截器在调用第二个方法时,是通过服务本身调用,而不是通过代理,导致我从我的服务调用第一个方法没有被拦截,因此没有被缓存。

我怎样才能让它工作?

更新:添加示例代码

这在我的头上很抱歉,如果任何东西似乎没有编译

这是服务类的示例

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 时,会触发拦截器,但不会从 Service 本身的 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);
    }
}

【问题讨论】:

    标签: ninject ninject-extensions ninject-interception


    【解决方案1】:

    我找到了解决方案/有关问题的更多详细信息。

    如果我去掉GetObject方法上的virtual修饰符,那么它就不会被拦截了,当它调用GetObjects时,就会触发拦截器。

    所有这一切让我想到,如果我希望这两种方法都被拦截,我需要让拦截器深入工作,如果这甚至可能的话。

    【讨论】:

      猜你喜欢
      • 2013-10-01
      • 2012-08-18
      • 2018-09-04
      • 2014-10-11
      • 2021-05-17
      • 1970-01-01
      • 2015-08-14
      相关资源
      最近更新 更多