问题
I have just upgraded a relatively large codebase from Ninject 2.2 to Ninject 3.0. Everything seems to be going as planned except I had to make a few changes to the interception stuff that we use.
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>();
This cut-down version is what we used to great effect with Ninject 2.3. Because interface proxies were not allowed, we had all methods marked as virtual and that enabled the Castle dynamic proxy to override them.
Now I want to move the [LogMethod] to the interface level to use interface proxies:
However, when I move it, Ninject no longer detects that I want to intercept this class. Also if I leave it as is, a subtler problem occurs:
The invocation.Request.Method
is the MethodInfo from the Interface IFoo
- not the implementation Foo
, this means that I cannot retrieve my attribute any more. So I am stuck between these two issues for the moment - If I put the attribute in the interface, Ninject doesn't create the proxy, if I put the attribute in the implementation, I cannot easily retrieve my attribute to access it's properties. At the moment my only solution is this:
interface IFoo
{
[LogMethod(Level = LogLevel.Error)]
Bar GetBar();
}
class Foo : IFoo
{
[LogMethod(Level = LogLevel.Error)]
public virtual Bar GetBar()
{
return new Bar();
}
}
Or use the InterfaceMapping to convert my IFoo MethodInfo
to the invocation.Request.Target.GetType()
(which returns the implementation type - Foo
) MethodInfo
.
Any recommendations?
来源:https://stackoverflow.com/questions/13494767/ninject-interception-3-0-interface-proxy-by-method-attributes