问题描述
我想Ninject创建绑定的所有类型的实现一个通用接口一个特定的组件内,不指定他们都在运行。有点像开放式泛型如何Autofac工作。
I want Ninject to create Bindings for all types within a specific assembly that implement a generic interface, without specifying them all at runtime. Kind of like how open generics work in Autofac.
这就是我想出了...
This is what i came up with...
kernel.Bind(x => x.FromThisAssembly()
.SelectAllClasses()
.Where(t => t.IsAssignableFrom(
typeof(ICommandHandler<>)))
.BindAllInterfaces());
调用下面的方法,我希望所有类型实施 ICommandHandler&LT的数组; T&GT;
,但它产生什么...
Calling the method below, i would expect an array of all types implementing ICommandHandler<T>
but it yields nothing...
public void Process<TCommand>(TCommand command)
where TCommand : ICommand
{
var handlers =
_kernel.GetAll<ICommandHandler<TCommand>>();
foreach(var handler in handlers)
{
handler.Handle(command);
}
}
有没有一个现有的方式来实现这一目标?或者我需要使用的约定API来推出自己的?
Is there an existing way to achieve this? Or do I need to roll my own using the conventions API?
这似乎是一个相当普遍的模式,并想知道这是否可以不写我自己的实现来实现。
It seems like a fairly common pattern and was wondering if this can be achieved without writing my own implementation.
推荐答案
您绑定做是因为两个问题完全无关:
Your binding is doing exactly nothing because of two problems:
-
IsAssignableFrom希望以相反的顺序参数。您指定的
IsAssignableFrom expects the parameters in the opposite order. You specified
SomeCommand x = new ICommand<>();
一个封闭泛型类是不能分配给一个开放的泛型类型。或者换句话说
A closed generic class is not assignable to an open generic type. Or in other words
ICommand<> x = new SomeCommand();
是无效的code。
is not valid code.
你想要的是:
kernel.Bind(x => x.FromThisAssembly()
.SelectAllClasses().InheritedFrom(typeof(ICommandHandler<>))
.BindAllInterfaces());
这篇关于在Ninject 3.0绑定泛型类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!