У меня есть базовый класс для классов, которые могут выступать в качестве плагинов для центральной системы. Я хочу, чтобы эти плагины были определены в сторонних сборках. Центральная система создает экземпляры плагинов на основе некоторых аргументов командной строки.Используя ninject, могу ли я создать привязку к классу, который имеет атрибут и удовлетворяет предикату?
Для достижения этой цели я создал атрибут, что эти классы могут быть украшены, что-то вроде:
[ArgName("some-module")]
И в момент их инициализации, я использую кусок кода, который отражается на все загруженные типы, пытаясь найти тот, у которого есть атрибут и правильный параметр:
AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(x => x.GetTypes())
.SingleOrDefault(x => /* check for attribute and predicate */);
Это прекрасно работает.
Но я чувствую, что я заново изобретаю то, что может иметь каркас DI самостоятельно. Итак, поскольку я уже использую Ninject для некоторых других зависимостей в своем проекте, мне было интересно: есть ли способ передать эту ответственность Ninject, а не писать код пользовательского отражения?
Другими словами, это Ninject уже есть что-то я пропустил, что делает примерно следующее:
kernel.Bind<ModuleBase>()
.ToTypesThatHaveThisAttribute<ArgName>()
.With(x => x.Name == userProvidedCommandlineArgument);
Конечно, я знаю, что могу создать вышеупомянутые методы расширения для BindingToSyntax<T>
и сделать синтаксис лучше, где он используется. Но я хотел бы изгнать код отражения вообще, если Ninject имеет встроенную функциональность.
Посмотрите на библиотеку Ninject.Extensions.Conventions, у нее есть много дополнительных функций, особенно для таких сценариев привязки «пакетной». https://github.com/ninject/Ninject.Extensions.Conventions –