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, сработает инсерцептор.
Все это заставило меня задуматься, что если я хочу, чтобы оба метода были перехвачены, я должен заставить перехватчик работать глубоко, если это вообще возможно.