Ninject: More than one matching bindings are available same class twice

1.5k Views Asked by At

Given this class:

public class UserQueryHandler : 
    IQueryHandler<UserCredentialsByUsernameQuery, UserJWTIdentity>,
    IQueryHandlerAsync<UserRoleByUserNameQuery, UserRole>
{

//..implementation }

public interface IQueryHandler<TParameter, TResult>
{
    TResult Retrieve(TParameter query);
}
public interface IQueryHandlerAsync<TParameter, TResult>
{
    Task<TResult> RetrieveAsync(TParameter query);
}

And the following Ninject configuration:

kernel.Bind(x => x
       .FromThisAssembly()
       .SelectAllClasses().InheritedFrom(typeof(IQueryHandler<,>))
       .BindAllInterfaces());

            kernel.Bind(x => x
             .FromThisAssembly()
             .SelectAllClasses().InheritedFrom(typeof(IQueryHandlerAsync<,>))
             .BindAllInterfaces());

I'm getting the following error:

More than one matching bindings are available.

Matching bindings:

1) binding from IQueryHandlerAsync{UserRoleByUserNameQuery, UserRole} to UserQueryHandler

2) binding from IQueryHandlerAsync{UserRoleByUserNameQuery, UserRole} to UserQueryHandler

Activation path:

1) Request for IQueryHandlerAsync{UserRoleByUserNameQuery, UserRole}

When trying to get an instance using this:

var handler = _kernel.Get<IQueryHandlerAsync<UserRoleByUserNameQuery, UserRole>>();

The suspicious thing is that I don't get the error trying to instantiate the other interface implementation:

var handler = _kernel.Get<IQueryHandler<UserCredentialsByUsernameQuery, UserJWTIdentity>>();

And the error disapears if I create a separated class that implements only that interface:

public class UserQueryHandler2 : 
    IQueryHandlerAsync<UserRoleByUserNameQuery, UserRole>
{
//..implementation works fine!! }

From what I understand, the class is being binded twice, but I don't understand why is this happening (probably a bug?)

1

There are 1 best solutions below

1
On

BindAllInterfaces is binding all the interfaces the type inherits from, which in the case of UserQueryHandler is both IQueryHandler and IQueryHandlerAsync. So your type is being bound to IQueryHandlerAsync in the first portion of your Ninject configuration when it's scanning for all types that inherit from IQueryHandler.