Где я должен делать инъекцию с помощью Ninject 2+ (и как я могу упорядочить свои модули?)
У меня есть решение с двумя соответствующими (на этот вопрос) проектами и несколькими другими;
- Библиотека классов с функциональностью, используемой несколькими другими проектами.
- Приложение ASP.NET MVC.
Мой вопрос в основном, где я должен делать IoC с Ninject 2, учитывая...
- Библиотека классов нуждается в некоторой любви DI, среди прочего, в классах репозитория, которым нужны веб-запросы для определенных объектов сеанса (думаю, Единица работы).
- Для 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? Его следует использовать только в Root, который в вашем случае соответствует Global.asax. Вы можете прочитать немного об этом в этом SO-ответе - хотя этот вопрос касается Windsor, принцип остается тем же.
Как насчет ваших тестов? Они также должны быть совершенно не осведомлены о контейнере DI. Подробнее см. этот другой ответ SO.
DI может быть достигнуто в вашей библиотеке при обильном использовании Инъекции конструктора. Вам не нужно ссылаться на любой контейнер DI, чтобы сделать это, но это облегчает жизнь, если вы используете контейнер DI для разрешения всех зависимостей от корня композиции.