Найдите класс, который реализует общий интерфейс с Ninject

С помощью Ninject вы можете зарегистрировать такую ​​привязку:

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

Но в моем случае я не знаю имени фактического класса. Все, что я знаю, это то, что он реализует определенный интерфейс.

Так, например, предположим, что у меня есть следующее:

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

Будет только один класс, который реализует интерфейс с этими общими параметрами: IQueryHandler<CreatePage, string>

Есть ли способ с Ninject динамически получить экземпляр класса? Что-то типа:

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

Обратите внимание:

Я не хочу вручную bind делать это в методе RegisterServices. Я ищу динамический способ получить экземпляр класса.


person w00    schedule 26.07.2017    source источник


Ответы (3)


Ninject содержит API пакетной регистрации. Например, вы можете использовать следующую привязку:

kernel.Bind(
    x => x.FromAssembliesMatching("Fully.Qualified.AssemblyName*")
    .SelectAllClasses()
    .InheritedFrom(typeof(IQueryHandler<,>))
    .BindBase()
);
person Steven    schedule 26.07.2017
comment
Я установил Ninject.Extensions.Conventions. Но метод bind по-прежнему не принимает лямбда. Есть ли что-нибудь еще, что мне нужно для этого? - person w00; 26.07.2017
comment
тб, я не знаю. Я скопировал пример из этого ответа. - person Steven; 26.07.2017

С помощью этого кода вы получите все типы, реализующие IQueryHandler.

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

После этого вы можете зарегистрировать типы в Ninject или вручную создать экземпляр из одного из типов:

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

Я не тестировал этот код, на .Net Core есть другой способ получить все типы из сборки

person Noren    schedule 26.07.2017
comment
Все становится немного сложнее, когда нет неуниверсального IQueryHandler. В вопросе кажется только общий интерфейс IQueryHandler<,>. - person Steven; 26.07.2017

Я думаю, вам нужны расширения соглашения Ninject.

См. https://github.com/ninject/Ninject.Extensions.Conventions.

person Jan Muncinsky    schedule 26.07.2017