3

我正在使用 .NET 4.5,Ninject 3 和约定 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 等)添加绑定......

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

4

1 回答 1

0

编辑:不编译[并且它没有揭示要求的事实没有意义],请参阅评论中此结论的推理。


这只是正常的开放泛型案例。正如我之前评论中的链接所提到的,使 DRY 看起来的基本绑定方式很简单:

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

然后,此绑定将足以T满足ICommandHandler<MyGenericCommand<T>>.

在将基于约定的绑定绑定到您所期望的映射的上下文中,问题在于SelectAllClasses().InheritedFrom(typeof(ICommandHandler<>))不包括泛型类——这是有道理的,因为您很少可以在非具体类上指定泛化规则。

你可以

  • 使用 DSL 的不同 Projection 部分来选择 Generic 类,然后以某种基于约定的方式绑定它们
  • NinjectModule从程序集中公开 a公开执行上述操作的 [open] 通用服务,Bind然后执行kernel.Load()模块 [prob by the DLL name pattern]。
于 2013-05-27T14:51:15.410 回答