2

With Ninject you can register a binding like this:

Bind(typeof(IQueryHandler<,>)).To(typeof(QueryHandler<,>));

But in my case I don't know the name of the actual class. All i know is that it implements a certain interface.

So for example, suppose I have the following:

public class CreatePageQueryHandler : IQueryHandler<CreatePage, string>
{
    public string Retrieve(CreatePage query)
    { ... }
}

There will be only one class that implements the interface with these gerenic params: IQueryHandler<CreatePage, string>

Is there a way with Ninject to dynamically get an instance of the class? Something like:

kernel.Get<IQueryHandler<CreatePage, string>>(); // returns instance of: CreatePageQueryHandler 

Please note:

I don't want to manually bind this in the RegisterServices method. I'm looking for a dynamic way to get the instance of the class.

w00
  • 26,172
  • 30
  • 101
  • 147

3 Answers3

3

Ninject contains a batch-registration API. You can use the following binding for instance:

kernel.Bind(
    x => x.FromAssembliesMatching("Fully.Qualified.AssemblyName*")
    .SelectAllClasses()
    .InheritedFrom(typeof(IQueryHandler<,>))
    .BindBase()
);
Steven
  • 166,672
  • 24
  • 332
  • 435
  • I've installed `Ninject.Extensions.Conventions`. But the `bind` method still doesn't accept a lamda. Is there anything else I need for this? – w00 Jul 26 '17 at 11:00
  • tbh, I don't know. I copied the example from [this answer](https://stackoverflow.com/a/40284170/264697). – Steven Jul 26 '17 at 11:48
1

With this Code you will get all types which implements IQueryHandler.

var types = AppDomain.CurrentDomain.GetAssemblies()
    .SelectMany(s => s.GetTypes())
    .Where(p => typeof(IQueryHandler).IsAssignableFrom(p));

After that you can register the types in Ninject or you can manually create a Instance from one of the Type:

var instance = (IQueryHandler)Activator.CreateInstance(types.First());

I did not test this Code, on .Net Core there is a different way to get all types from an assembly

Noren
  • 339
  • 3
  • 6
  • Things get a bit more complicated when there is no non-generic `IQueryHandler`. In the question there only seems to be a generic `IQueryHandler<,>` interface. – Steven Jul 26 '17 at 10:49
1

I think you need Ninject convention extensions.

See https://github.com/ninject/Ninject.Extensions.Conventions

Jan Muncinsky
  • 4,282
  • 4
  • 22
  • 40