Где я должен делать инъекции с Ninject 2+ (и как мне расположить свои модули?)

У меня есть решение с двумя соответствующими (к этому вопросу) проектами и несколькими другими;

  1. Библиотека классов с функциональностью, используемой несколькими другими проектами.
  2. ASP.NET MVC приложение.

Мой вопрос в основном, где я должен делать IoC с Ninject 2, учитывая...

  • Библиотека классов нуждается в некоторой DI-любви, в том числе в классах репозитория, которым нужны веб-запросы для конкретных объектов сеанса (например, Unit of Work).
  • Приложение MVC нуждается в DI, поскольку с Ninject 2 вы в основном наследуетесь от NinjectHttpApplication.
  • Модульные тесты для библиотеки классов должны знать об этом, чтобы внедрить другой набор репозиториев.
  • Модульные тесты для веб-приложения должны вводиться по той же причине.

Я заглянул сюда в ментальный угол, потому что видел только три варианта для начала. DI в библиотеке классов, DI в веб-приложении или оба, но есть проблемы с каждым:

  • Я не могу сделать DI только в библиотеке классов, так как приложение MVC для начала должно наследоваться от NinjectHttpApplication.
  • Я не могу сделать DI только в приложении MVC - библиотека классов, в конце концов, используется другими библиотеками, и приложение MVC в любом случае не должно знать слишком много о внутренностях библиотеки.
  • Я думаю, что это единственный выход, который я вижу: независимый IoC для обоих проектов. Библиотека классов и приложение MVC имеют свои собственные настройки IoC и выполняют DI для своих вещей, не заботясь друг о друге.

У кого-нибудь есть "лучшие практики" или рекомендации о том, как сделать что-то подобное? Я не могу себе представить, что я первый, кто попал в такую ​​ситуацию, и было бы неплохо узнать, каков "правильный" способ сделать это...

Спасибо!

1 ответ

Решение

Я не знаю NInject, но если он не работает значительно иначе, чем Windsor, StructureMap и т. Д., Ответы, как правило, остаются прежними, так как существуют некоторые общие шаблоны DI. С этим в мыслях:

Первое, что нужно понять, это то, что DI не привязан к конкретной среде, такой как NInject или Windsor. Это набор методов и шаблонов проектирования, которым нужно следовать. Вы можете сделать DI вручную, используя так называемый DI Бедного Человека, но, очевидно, он становится намного лучше с Контейнером DI.

Почему это актуально? Это уместно, потому что, как только вы это поймете, вывод состоит в том, что подавляющее большинство кода вашего приложения не должно знать о DI-контейнере.

Так где вы используете DI-контейнер? Он должен использоваться только в корне композиции, который в вашем случае будет соответствовать Global.asax. Вы можете прочитать немного больше об этом в этом ответе SO - хотя этот вопрос о Виндзоре, принцип остается тем же.

Как насчет ваших юнит-тестов? Они также должны совершенно не знать о DI-контейнере. Смотрите этот другой SO ответ для более подробной информации.

DI может быть достигнуто в вашей библиотеке с обильным использованием Constructor Injection. Для этого вам не нужно ссылаться на какой-либо DI-контейнер, но это значительно облегчает жизнь, если вы используете DI-контейнер для разрешения всех зависимостей из корня композиции.

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