Ninject Interception 3.0 Interface proxy by method attributes

a 夏天 提交于 2019-12-25 06:26:29

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!