Ninject Interception 3.0 Интерфейсный прокси по атрибутам метода
Я только что обновил относительно большую кодовую базу с Ninject 2.2 до Ninject 3.0. Кажется, все идет по плану, за исключением того, что мне пришлось внести несколько изменений в перехватчики, которые мы используем.
interface IFoo
{
Bar GetBar();
}
class Foo : IFoo
{
[LogMethod(Level = LogLevel.Error)]
public virtual Bar GetBar()
{
return new Bar();
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
class LogMethodAttribute : InterceptAttribute
{
public override IInterceptor CreateInterceptor(IProxyRequest request)
{
return request.Kernel.Get<ILogMethodInterceptor>();
}
public LogLevel Level { get; set; }
}
interface ILogMethodInterceptor : IInterceptor { }
class LogMethodInterceptor : ILogMethodInterceptor
{
public void Intercept(IInvocation invocation)
{
LogMethodAttribute attr = (LogMethodAttribute)invocation.Request.Method.GetCustomAttributes(typeof(LogMethodAttribute), true).FirstOrDefault();
// Log something - using attribute properties
}
}
NinjectSettings settings = new NinjectSettings { LoadExtensions = false };
IKernel kernel = new StandardKernel(settings, new DynamicProxy2Module());
kernel.Bind<ILogMethodInterceptor>().To<LogMethodInterceptor>();
kernel.Bind<IFoo>().To<Foo>();
Эта урезанная версия - то, что мы использовали для большого эффекта в Ninject 2.3. Поскольку интерфейсные прокси не были разрешены, у нас были все методы, помеченные как виртуальные, и это позволило динамическому прокси-серверу Castle переопределять их.
Теперь я хочу переместить [LogMethod] на уровень интерфейса, чтобы использовать интерфейсные прокси:
Однако, когда я перемещаю его, Ninject больше не обнаруживает, что я хочу перехватить этот класс. Также, если я оставлю все как есть, возникнет более тонкая проблема:
invocation.Request.Method
такое MethodInfo из интерфейса IFoo
- не реализация Foo
это означает, что я больше не могу получить свой атрибут. Так что я застрял между этими двумя проблемами на данный момент - если я добавлю атрибут в интерфейс, Ninject не создаст прокси, если я добавлю атрибут в реализацию, я не смогу легко получить свой атрибут для доступа к его свойствам. На данный момент мое единственное решение заключается в следующем:
interface IFoo
{
[LogMethod(Level = LogLevel.Error)]
Bar GetBar();
}
class Foo : IFoo
{
[LogMethod(Level = LogLevel.Error)]
public virtual Bar GetBar()
{
return new Bar();
}
}
Или используйте InterfaceMapping для конвертации моего IFoo MethodInfo
к invocation.Request.Target.GetType()
(который возвращает тип реализации - Foo
) MethodInfo
,
Любые рекомендации?