Ninject Interception: служба, вызывающая перехваченный метод, не перехватывается при вызове внутри себя

У меня есть сервисный класс, введенный с 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>());

Поэтому, когда я вызываю GetObjects из любого класса, в который внедряется IService, перехватчик срабатывает, но не запускается из метода 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);
    }
}

1 ответ

Я нашел решение / более подробно по проблеме.

Если я удалю виртуальный модификатор в методе GetObject, он больше не будет перехватываться, и когда он вызовет GetObjects, сработает инсерцептор.

Все это заставило меня задуматься, что если я хочу, чтобы оба метода были перехвачены, я должен заставить перехватчик работать глубоко, если это вообще возможно.

Другие вопросы по тегам