Ninject Interception 3.0接口代理方法属性

时间:2012-11-21 13:52:20

标签: c# ninject ninject-extensions ninject-interception

我刚刚将一个相对较大的代码库从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是接口IFoo中的MethodInfo - 而不是实现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()(返回实现类型 - FooMethodInfo

有什么建议吗?

0 个答案:

没有答案