基于Ninject约定的绑定+装饰器

时间:2013-05-30 07:07:50

标签: c# .net ninject

我们正在使用基于Ninjects约定的绑定来自动将一组命令和查询绑定到其处理程序。到目前为止,我们有一个装饰器使用以下工具。

绑定所有没有属性:

    Kernel.Bind(x =>
      x.FromThisAssembly()
       .SelectAllClasses()
       .InheritedFrom(typeof(ICommandHandler<>))
       .WithoutAttribute<DoCheckAttribute>()
       .BindAllInterfaces());

使用属性绑定所有内容:

    Kernel.Bind(x =>
      x.FromThisAssembly()
       .SelectAllClasses()
       .InheritedFrom(typeof(ICommandHandler<>))
       .WithAttribute<DoCheckAttribute>()
       .BindAllInterfaces()
       .Configure(c => c.WhenInjectedInto(typeof(DoCheckDecorator<>))));

我们尝试了以下方法来添加另一个装饰器,但这失败了。

绑定所有没有属性:

    Kernel.Bind(x =>
      x.FromThisAssembly()
       .SelectAllClasses()
       .InheritedFrom(typeof(ICommandHandler<>))
       .WithoutAttribute<DoCheckAttribute>()
       .WithoutAttribute<DoOtherCheckAttribute>()
       .BindAllInterfaces());

使用属性绑定所有内容:

    Kernel.Bind(x =>
      x.FromThisAssembly()
       .SelectAllClasses()
       .InheritedFrom(typeof(ICommandHandler<>))
       .WithAttribute<DoCheckAttribute>()
       .WithoutAttribute<DoOtherCheckAttribute>()
       .BindAllInterfaces()
       .Configure(c => c.WhenInjectedInto(typeof(DoCheckDecorator<>))));

    Kernel.Bind(x =>
      x.FromThisAssembly()
       .SelectAllClasses()
       .InheritedFrom(typeof(ICommandHandler<>))
       .WithoutAttribute<DoCheckAttribute>()
       .WithAttribute<DoOtherCheckAttribute>()
       .BindAllInterfaces()
       .Configure(c => c.WhenInjectedInto(typeof(DoOtherCheckDecorator<>))));

使用Ninject可以通过这种方式实现这一目标吗?我们是否必须回滚以手动定义每个绑定,即<?p>

    Bind<X>.To<Y>.WhenInjectedInto(?)

理想情况下,我们会使用以下语法:

    Bind<X>.To<Y>.WithDecorator<Z>.When(a => a.HasAttribute<DoCheckAttribute>)

1 个答案:

答案 0 :(得分:3)

所以似乎Ninject已经有了一个可以解决这个问题的扩展。使用拦截器扩展可以将属性写为:

    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
    public sealed class DoCheckAttribute : InterceptAttribute
    {
        public override IInterceptor CreateInterceptor(IProxyRequest request)
        {
            return request.Context.Kernel.Get<DoCheckInterceptor>();
        }
    }

然后将实际拦截写为:

    public class DoCheckInterceptor : IInterceptor
    {
         public void Intercept(IInvocation invocation)
         {
            //Do Work
            invocation.Proceed();
         }
    }

这意味着绑定变得如此简单:

    Kernel.Bind(x =>
       x.FromThisAssembly()
        .SelectAllClasses()
        .InheritedFrom(typeof(ICommandHandler<>))
        .BindAllInterfaces());

现在可以轻松添加新属性,而无需对绑定进行任何更改。多个属性也可以具有定义的运行顺序,例如:

     [DoCheck(Order = 0), DoOtherCheck(Order = 1)]
     public class TestClass
     {
     }