Binding Generic Types in Ninject 3.0

空扰寡人 提交于 2019-12-24 02:30:35

问题


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:

  1. IsAssignableFrom expects the parameters in the opposite order. You specified

    SomeCommand x = new ICommand<>();
    
  2. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!