问题描述
我使用.NET 4.5,Ninject 3 作为绑定如下:
kernel.Bind(X => X
.FromAssembliesMatching( assembly.dll)
.SelectAllClasses()InheritedFrom(typeof运算(ICommandHandler<>))
.BindAllInterfaces());
这是正确约束力的:
公共类MyCommandHandler:ICommandHandler< MyCommand>
但不绑定:
公共类MyGenericCommandHandler< T> :ICommandHandler< MyGenericCommand< T>>
不过,以前的绑定工作,如果我增加对具体的实现我的泛型类的,如个人绑定
kernel.Bind(typeof运算(ICommandHandler< MyGenericCommand<浮动>>))
。要(typeof运算(MyGenericCommandHandler<浮动>))
kernel.Bind(typeof运算(ICommandHandler< MyGenericCommand< INT>>))
。要(typeof运算(MyGenericCommandHandler< INT>))
但添加每个单独的一般类型违背约定的目的,需要添加对每个可能的个别类型如浮动结合,整型,字符串,等等...
EDIT: Doesn't compile [and the fact it doesn't reveals the requirement doesn't make sense], see reasoning for this conclusion in the comments.
This is just the normal open generics case. As alluded to with a link in my earlier comment, the way a basic bind to make that DRY looks is simply:
kernel.Bind(typeof(ICommandHandler<MyGenericCommand<>>))
.To(typeof(MyGenericCommandHandler<>));
This binding will then suffice for any T
variant of ICommandHandler<MyGenericCommand<T>>
.
In the context of doing convention based binding it to mapping what you're expecting, the problem is that SelectAllClasses().InheritedFrom(typeof(ICommandHandler<>))
does not include generic classes -- this makes sense as it's rare that you can specify generalized rules on non concrete classes.
You can either
- use a different Projection portion of the DSL to select the Generic classes and then bind them in some convention based manner
- expose a
NinjectModule
from assemblies exposing [open] generic services which does the aboveBind
and then do akernel.Load()
of the module [prob by the DLL name pattern].
这篇关于Ninject通过绑定不公约泛型类型的工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!