Если бы я не использовал DI-контейнер, мне бы не пришлось ссылаться
Библиотека EntityFramework в моем приложении MVC3
Даже при использовании контейнера DI вы не должны позволять вашему проекту MVC3 ссылаться на EF, но вы (неявно) решаете сделать это путем реализации Composition Root (путь запуска, где вы создаете ваши графы объектов) внутри вашего проекта MVC3. Если вы очень строго относитесь к защите своих архитектурных границ с помощью сборок, вы можете переместить корень композиции или презентацию (MVC) в библиотеку классов.
В первом варианте вы позволите вашему проекту MVC3 ссылаться на эту отдельную сборку «начальной загрузки», и она будет ссылаться на все другие сборки в вашем решении, а также на вашу библиотеку контейнеров DI. Проблема в том, что этот проект начальной загрузки не может ссылаться на типы, расположенные в проекте MVC3 (потому что это вызовет зависимость циклической сборки). Эти типы должны быть перемещены в проект загрузчика (который, возможно, должен ссылаться на System.Web.Mvc), или вам нужно сохранить небольшую часть конфигурации контейнера в приложении MVC3. Также обратите внимание, что ваш проект MVC по-прежнему ссылается на все другие сборки косвенно через новую сборку загрузчика, поскольку зависимости сборки являются переходными.
Хотя размещение корня композиции в отдельной сборке допустимо, большинство пуристов DI (включая меня) обычно перемещают корень композиции в библиотеку классов только при наличии нескольких конечных приложений (т. Е. Веб-приложение + веб-служба). + служба Windows), которые используют тот же бизнес-уровень. Когда у меня есть одно приложение, я сохраняю Composition Root внутри моего конечного приложения.
Второй вариант - переместить все связанные с MVC классы (представления, контроллеры и т. Д.) Из запускаемого проекта в библиотеку классов. Это позволяет этой новой сборке уровня представления оставаться отключенной от остальной части приложения. Сам проект вашего веб-приложения станет очень тонкой оболочкой с необходимой логикой запуска. Проект веб-приложения будет корнем компоновки, который ссылается на все остальные сборки.
Извлечение логики представления в библиотеку классов может усложнить работу с MVC. Будет все сложнее соединить, так как контроллеров и представлений, изображений, CSS-файлов и т. Д. Нет в стартовом проекте. Это, вероятно, выполнимо, но для установки потребуется больше времени.
Оба варианта имеют свои недостатки, и поэтому я обычно советую просто оставить корень композиции в веб-проекте. Многие разработчики не хотят, чтобы их сборка MVC зависела от сборки DAL, но на самом деле это не проблема. Не забывайте, что сборки являются артефактом развертывания ; Вы разбиваете код на несколько сборок, чтобы код мог быть развернут отдельно. С другой стороны, архитектурный слой - это логический артефакт. Очень возможно (и часто) иметь несколько слоев в одной сборке.
В этом случае мы получим корень композиции (слой) и слой представления в одном проекте веб-приложения (таким образом, в одной сборке). И хотя эта сборка ссылается на сборку, содержащую DAL, Presentation Layer по-прежнему не ссылается на Data Access Layer . Это большая разница.
Конечно, когда мы делаем это, мы теряем возможность для компилятора проверять это архитектурное правило во время компиляции, но это не должно быть проблемой.Большинство архитектурных правил на самом деле не могут быть проверены компилятором, и всегда есть что-то вроде здравого смысла.И если в вашей команде нет здравого смысла, вы всегда можете использовать обзоры кода (что, кстати, должна делать каждая команда, IMO).Вы также можете использовать такой инструмент, как NDepend (коммерческий), который поможет вам проверить ваши архитектурные правила.Когда вы интегрируете NDepend с вашим процессом сборки, он может предупредить вас, когда кто-то проверит код, нарушающий такое архитектурное правило.
Более подробное обсуждение того, как работает корень композиции, можно прочитать в главе 4 моей книги Внедрение зависимостей, принципы, практика, шаблоны .