公约的Ninject绑定不适用于泛型类型

时间:2013-05-26 23:27:49

标签: c# generics dependency-injection ninject ninject-extensions

我正在使用.NET 4.5,Ninject 3和the binding by convention lib如下:

kernel.Bind(x => x
    .FromAssembliesMatching("assembly.dll")
    .SelectAllClasses().InheritedFrom(typeof(ICommandHandler<>))
    .BindAllInterfaces());

这适用于:

public class MyCommandHandler : ICommandHandler<MyCommand>

绑定:

public class MyGenericCommandHandler<T> : ICommandHandler<MyGenericCommand<T>>

但是,如果我为我的泛型类的特定实现添加单独的绑定,则以前的绑定有效,例如:

kernel.Bind(typeof(ICommandHandler<MyGenericCommand<float>>))
      .To(typeof(MyGenericCommandHandler<float>))
kernel.Bind(typeof(ICommandHandler<MyGenericCommand<int>>))
      .To(typeof(MyGenericCommandHandler<int>))

但是添加每个单独的泛型类型会违反约定的目的,并且需要为每个可能的单个类型添加绑定,例如float,int,string等...

  

您知道如何修改约定或添加另一个约定(甚至是   提供完全不同的解决方案)来支持通用   我命令的版本?即支持两级泛型。

1 个答案:

答案 0 :(得分:0)

编辑:不编译[以及事实并未表明要求没有意义],请参阅评论中对此结论的推理。


这只是普通的开放式仿制药案例。正如我之前的评论中提到的一个链接所提到的那样,使DRY看起来基本绑定的方式很简单:

kernel.Bind(typeof(ICommandHandler<MyGenericCommand<>>))
    .To(typeof(MyGenericCommandHandler<>));

此约束对于T的任何ICommandHandler<MyGenericCommand<T>>变体都足够了。

在基于约定的上下文中将它绑定到映射您期望的内容时,问题是SelectAllClasses().InheritedFrom(typeof(ICommandHandler<>))不包含泛型类 - 这是有道理的,因为您很少可以在非上指定通用规则具体课程。

你可以

  • 使用DSL的其他Projection部分选择Generic类,然后以某种基于约定的方式绑定它们
  • 从暴露[open]泛型服务的程序集中公开NinjectModule,这些服务执行上述Bind,然后执行模块的kernel.Load() [概述DLL名称模式]。