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), И из-за некоторых внутренних органов это не может быть легко изменено.

Другие вопросы по тегам