С помощью Ninject вы можете зарегистрировать привязку следующим образом:
Bind(typeof(IQueryHandler<,>)).To(typeof(QueryHandler<,>));
Но в моем случае я не знаю названия фактического класса. Все, что я знаю, это то, что он реализует определенный интерфейс.
Например, предположим, что у меня есть следующее:
public class CreatePageQueryHandler : IQueryHandler<CreatePage, string>
{
public string Retrieve(CreatePage query)
{ ... }
}
Будет только один класс, который реализует интерфейс с этими параметрами IQueryHandler<CreatePage, string>
: IQueryHandler<CreatePage, string>
Есть ли способ с Ninject динамически получить экземпляр класса? Что-то вроде:
kernel.Get<IQueryHandler<CreatePage, string>>(); // returns instance of: CreatePageQueryHandler
Пожалуйста, обратите внимание:
Я не хочу вручную bind
это в методе RegisterServices
. Я ищу динамический способ получить экземпляр класса.
Ninject содержит API регистрации пакетов. Вы можете использовать следующую привязку, например:
kernel.Bind(
x => x.FromAssembliesMatching("Fully.Qualified.AssemblyName*")
.SelectAllClasses()
.InheritedFrom(typeof(IQueryHandler<,>))
.BindBase()
);
С помощью этого кода вы получите все типы, которые реализуют IQueryHandler.
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => typeof(IQueryHandler).IsAssignableFrom(p));
После этого вы можете зарегистрировать типы в Ninject или вручную создать экземпляр из одного из Type:
var instance = (IQueryHandler)Activator.CreateInstance(types.First());
Я не тестировал этот код, на.Net Core есть другой способ получить все типы из сборки
IQueryHandler
. В этом вопросе есть только общий IQueryHandler<,>
.
Я думаю, вам нужны расширения для Ninject.
См. Https://github.com/ninject/Ninject.Extensions.Conventions
Ninject.Extensions.Conventions
. Но методbind
все еще не принимает лямду. Есть ли что-нибудь еще, что мне нужно для этого?