Search code examples
c#genericsninjectninject-extensions

How can I Bind by convention a generic interface to a multiple generic concrete type in Ninject


I have a multiple object that implements the same generic interface. So, I want to configure it using Ninject conventions but I don't know how to do it.

Right now I have these registrations

Bind<IQueryHandler<GetPagedPostsQuery, PagedResult<Post>>>().To<GetPagedPostsQueryHandler>();
Bind<IQueryHandler<GetPostByDateQuery, Post>>().To<GetPostByDateQueryHandler>();

I tried this convention

Kernel.Bind(x => x
  .FromThisAssembly()
  .IncludingNonePublicTypes()
  .SelectAllClasses()
  .InheritedFrom(typeof(IQueryHandler<,>))
  .BindDefaultInterface());

But doesn't register any query handler.

Is posible to do it with conventions?

** Edit ** The classes are the followings

public class GetPagedPostsQueryHandler : IQueryHandler<GetPagedPostsQuery, PagedResult<Post>>
public class GetPostByDateQueryHandler : IQueryHandler<GetPostByDateQuery, Post>

Solution

  • BindDefaultInterface means that MyService : IMyService, IWhatever will be bound to IMyService.

    You should use BindSingleInterface, which worked instantly when I tried it in a Unit Test:

    [TestMethod]
    public void TestMethod2()
    {
        var kernel = new StandardKernel();
    
        kernel.Bind(c => c.FromThisAssembly()
                            .IncludingNonePublicTypes()
                            .SelectAllClasses()
                            .InheritedFrom(typeof(IQueryHandler<,>))
                            .BindSingleInterface());
    
        kernel.TryGet<IQueryHandler<GetPagedPostsQuery,PagedResult<Post>>>()
            .Should()
            .NotBeNull();
    }