2009-09-25 2 views
37

У меня есть решение с двумя соответствующими (на этот вопрос) проектами и несколькими другими;Где я должен делать инъекцию с помощью Ninject 2+ (и как я могу упорядочить свои модули?)

  1. Классная библиотека с функциональностью, используемой несколькими другими проектами.
  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

related: http://stackoverflow.com/questions/5267525/dal-bll-gui-composition-root-how-to-setup-di-bindings –

+1

Дублируйте с некоторыми комментариями, заслуживающими внимания для полноты, если вы действительно пытаясь получить полную информацию http://stackoverflow.com/questions/5733591/best-location-for-fluent-ioc-configuration-modules-currently-trying-ninject –

ответ

63

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

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

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

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

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

DI может быть получен в вашей библиотеке при обильном использовании Конструкция Инъекция. Вам не нужно ссылаться на любой контейнер DI, чтобы сделать это, но это облегчает жизнь, если вы используете контейнер DI для разрешения всех зависимостей от корня композиции.

+0

Привет, Марк - спасибо за ответ, я думаю, что получаю это сейчас, по крайней мере, большинство из них. Однако, если MVC/Global.asax отвечает за настройку всех DI, нужно ли также вставлять в материал библиотеки классов? Учтите, что библиотеке классов может потребоваться сохранить для каждого запроса веб-запроса или что-то в этом роде, которое будет использоваться для построения всех классов репозитория. Должно ли MVC-приложение узнать об этом? Просто пытаюсь оборачивать голову «Правильной вещью». :) –

+1

Поскольку вы используете MVC, лучшим вариантом является использование настраиваемого ControllerFactory для создания контроллеров со всеми их зависимостями. Вы можете увидеть пример этого с помощью Windsor в исходном коде MvcContrib: http://github.com/mvccontrib/MvcContrib/blob/be0eb3addedf1775db719117e7fa73e516f74c8d/src/MvcContrib.Castle/WindsorControllerFactory.cs Если некоторые из зависимостей являются типами в вашей библиотеке , они должны быть импортированы контроллером. Если вам нужно передать экземпляры ISession в свою библиотеку, вы можете использовать ctx контроллера для этого - он уже будет настроен на ваш пользовательский Factory. –

+0

Еще раз спасибо, Марк. Я должен попробовать - ничего, по-видимому, ничего не делает. Ninject основан на модуле, поэтому я могу создать отдельный модуль в моей библиотеке классов, который также автоматически используется установкой IoC в приложении MVC. Мне просто нужно попробовать. Mucho gracias! –