Лучшее место для конфигурации / модулей Fluent IOC (в настоящее время пробует Ninject) - PullRequest
6 голосов
/ 20 апреля 2011

Я изо всех сил пытаюсь найти лучшее место, чтобы найти мою конфигурацию Ninject «Модули» (место, где указаны привязки типов).Я надеюсь, что я просто упускаю какой-то очевидный трюк, так как он начинает превращаться в посредника для меня с использованием быстрой конфигурации (и, следовательно, Ninject):

В простом веб-стеке, содержащем три отдельных проекта: Web, BusinessLogic, DataAccess.Я не хочу, чтобы веб-уровень имел прямую ссылку на уровень DataAccess , но я не могу обойти это, потому что:

  • Если я поставлю Модуль конфигурации DataAccess на уровне DataAccess , мне нужно сослаться на уровень DataAccess, чтобы я мог получить доступ к модулю конфигурации при создании экземпляра ядра Ninject на веб-уровне

  • Если япоместите Модуль конфигурации DataAccess на веб-уровне , я должен сослаться на слой DataAccess, чтобы иметь доступ к типам, которые я хочу связать

  • Если я поставлю Модуль конфигурации DataAccess в отдельном проекте конфигурации . В результате возникают проблемы с циклическими ссылками при попытке указать привязки для веб-уровня и уровня DataAccess.

Часть преимуществаIOC должен позволить слабую связь, но, насколько я вижу, использование Ninject потребовало бы от меня добавления более прямых ссылок на проекты, которые у меня есть в настоящее время.Чего мне не хватает?

Ответы [ 4 ]

5 голосов
/ 21 апреля 2011

Ninject не требует ссылки на сборки! Вы можете указать Kernel загрузить все модули из сборок, которые соответствуют определенному шаблону - см. Перегрузки Load()! Используя этот механизм, вы можете отобразить ваши функции как Модули, как @Daniel Marbach предложил в месте, где реализована каждая функция. Мне не нравятся эти огромные модули, определяющие каждую привязку для сборки. Я бы предпочел иметь каждого в определенном маленьком модуле для определенной функции.

Это также позволяет включать / отключать / заменять реализации без перекомпиляции других сборок (по крайней мере, если у вас есть интерфейсы в отдельных сборках).

Итак, в основном у вас есть:

  • Одна или несколько сборок веб-уровня: содержат контроллеры, представления и привязки для веб-уровня. Каждая из сборок ссылается на некоторые сборки, которые определяют интерфейсы, от которых она зависит.
  • Одна или несколько сборок, которые определяют интерфейсы для зависимостей веб-уровня.
  • Одна или несколько сборок бизнес-логики, реализующих все или некоторые интерфейсы, требуемые веб-уровнем. Ссылка на некоторые сборки, которые содержат интерфейсы объектов, от которых они зависят. Содержит модули, которые определяют привязки для компонентов, которые они предоставляют.
  • Одна или несколько сборок, которые определяют интерфейсы для зависимостей уровня бизнес-логики.
  • Одна или несколько сборок, которые реализуют зависимости уровня бизнес-логики и, возможно, некоторые из веб-уровня (например, данные, которые напрямую предоставляются без бизнес-логики). Содержит модули компонентов, которые они предоставляют.
  • Один загрузчик загружает модули этих сборок, используя kernel.Load("*.dll") или аналогичный.

Преимущество этого:

  • Нет ссылки с веб-уровня на уровень бизнес-логики и уровень данных
  • Нет ссылки с уровня бизнес-логики на уровень данных
  • Каждый слой заменяется без какого-либо воздействия на другие
3 голосов
/ 20 апреля 2011

Обычно я создаю сборку только для контейнера IOC и конфигурации; Затем эта сборка может ссылаться на все другие сборки и Ninject (или StructureMap в моем случае). Тогда веб-приложение просто должно ссылаться на сборку IOC и включать пару строк кода инициализации, которые напрямую используют сборку IOC.

Однако, одно замечание - Моя сборка IOC не ссылается на веб-сборку (что привело бы к циклической ссылке). Все, что нужно ввести, определяется вне веб-сборки, поэтому для меня это не проблема.

2 голосов
/ 21 апреля 2011

Лучший способ организовать ваши модули - это особенность! Например

  • AuthenticationModule
  • OrderModule
  • CustomerModule

Веселись!

0 голосов
/ 21 апреля 2011

Я всегда помещаю Конфигурацию Ninject Modules в отдельную сборку, такую ​​как Acme.Common, и ссылаюсь на нее из Acme.Data, Acme.Domain и т. Д., Чтобы не было циклических зависимостей, я всегда могу заменить Acme.Common после некоторых изменений в регистрациях без неприятности.

...