问题
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());
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);
}
}
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.
回答1:
Your binding is doing exactly nothing because of two problems:
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();
is not valid code.
What you want is:
kernel.Bind(x => x.FromThisAssembly()
.SelectAllClasses().InheritedFrom(typeof(ICommandHandler<>))
.BindAllInterfaces());
来源:https://stackoverflow.com/questions/11702477/binding-generic-types-in-ninject-3-0