FromAssembliesMatching перезаписывает явно установленные привязки
Есть ли способ объединить вызов FromAssembliesMatching для автоматической настройки большинства интерфейсов и некоторых явных привязок? У меня есть следующий код, который должен установить все ISomething на Something автоматически, а затем установить специальный конструктор для интерфейса IUnitOfWork, где конкретная реализация принимает два bools в качестве аргументов:
kernel.Bind(x => x.FromAssembliesMatching("*.dll").SelectAllClasses()
.InNamespaces("MyNamespace").BindDefaultInterface());
kernel.Bind<IUnitOfWork>().ToConstructor(x => new UnitOfWork(true, false));
Однако, когда я пытаюсь вызвать TryGet следующим образом, я получаю нулевое значение:
kernel.TryGet<MyNamespace.IUnitOfWork>()
Он отлично работает, когда я переключаю порядок и вызываю исключение для реализации UnitOfWork явно при втором вызове:
kernel.Bind<IUnitOfWork>().ToConstructor(x => new UnitOfWork(true, false));
kernel.Bind(x => x.FromAssembliesMatching("*.dll").SelectAllClasses()
.InNamespaces("MyNamespace").Excluding(typeof(UnitOfWork))
.BindDefaultInterface());
Отмена порядка или пропущенный вызов Исключение результатов в null снова, когда я пытаюсь разрешить экземпляр IUnitOfWork.
Как правильно сочетать автоматическое сопоставление с явной конфигурацией? Я использую Ninject 3.2.0.0 и Ninject.Extensions.Conventions 3.2.0.0.
1 ответ
Есть два способа справиться с вашей ситуацией, один из которых вы уже нашли:
Excluding<>
тип из конвенции.- Преимущество: это не зависит от последовательности вашего "руководства" и ваших условных привязок.
- Недостаток: нужно ссылаться на особые случаи в двух местах, в соглашении и в "ручном" связывании
- с помощью
Rebind<IUnitOfWork>
вместо Bind.- Преимущество: вам не нужно ссылаться на специальный случай в двух местах.
- Недостаток: это работает, только если вы выполняете обязательное соглашение перед выполнением
Rebind
,
Конечно, вы также можете добавить атрибут ко всем типам, который должен быть исключен из соглашений, и соответствующим образом адаптировать ваши соглашения. Но я сомневаюсь, что так будет лучше.
Кстати, можно представить что-то вроде расширения соглашения для проверки того, существует ли уже привязка для этого типа, и создания новой привязки, только если она не существует. Помимо очевидных сложностей с много- и контекстными привязками, у ninject нет простого доступа, чтобы проверить, существует ли уже привязка для типа "реализации". Все, что есть IKernel.GetBindings(Type serviceType)
, И из-за некоторых внутренних органов это не может быть легко изменено.