Я читал много примеров кода для DI и autofac. Я заметил одну вещь: многие люди объединяют интерфейсы и реализации в один проект. С точки зрения дизайна, я считаю, что это неправильно, и все интерфейсы должны быть в отдельной сборке. Итак, я определяю свои проекты так:
UI - Web App/Windows App/Both
- Views
- Models
- Controllers/ ViewModels
Business
- Services/Processes
- Interfaces
- Model
DataAccess
- Repositories & UoW
- Interfaces
- Model
Таким образом, мои бизнес-сервисы относятся только к интерфейсам и моделям DataAccess, но остаются независимыми от фактической реализации. Таким же образом пользовательский интерфейс также относится только к бизнес-интерфейсам и модели, и между ними существует четкое разделение. Это также помогает мне при тестировании, когда я могу самостоятельно протестировать слой.
Мой вопрос касается объявления модуля Autofac. Мне нужно настроить мою сборку, чтобы скопировать реализации в каталог окончательного развертывания. Мои бизнес-модули должны относиться к реализации доступа к данным, а пользовательский интерфейс - для доступа к бизнес-модулям.
Я рассматриваю возможность сканирования сборки Autofac, но не уверен, что это единственный вариант. Также обратите внимание, что я уже следую соглашению об именах и в большинстве случаев я не собираюсь писать отдельные привязки. Меня беспокоит то, что
Мое мнение таково, что наличие интерфейсов и реализаций в отдельных сборках является чрезмерным и не обеспечивает ценности, потому что вам придется развернуть обе сборки, чтобы ваш проект работал. Мне нравится ссылаться на этот твит от Пола Стовелла, где он утверждает, что пространства имен - это единицы проблем, тогда как сборки - это единицы развертывания. Я считаю, что это очень мне нравится.
Вернемся к вашему вопросу: в конце концов, ваш исполняемый проект (веб-приложение или приложение для Windows) должен знать как об интерфейсах, так и о реализациях. Я считаю, что модули Autofac должны находиться в проекте верхнего уровня, следовательно, в нем должны быть ссылки на все необходимые проекты. Я объясняю это тем, что помимо определения регистраций служб вы также определяете время жизни для каждой из них. Это понятие зависит от проекта, который использует ваши зависимости; веб-проект может иметь некоторые службы, зарегистрированные для каждого HTTP-запроса, в то время как приложение Windows может иметь другое время жизни.
На мой взгляд, модули отлично подходят для группирования регистраций вместе, но это не значит, что они должны жить в том же проекте, что и сервисы, для которых он содержит регистрации.
Я не понимаю, как наличие интерфейсов и реализаций в отдельных сборках помогает при тестировании; то, содержит ли сборка только определение интерфейса или и интерфейс, и реализация, не должно влиять на тестирование. Что такое сборка начальной загрузки? Я бы не стал беспокоиться о ссылках в проекте верхнего уровня. Сборки нижнего уровня в любом случае попадут в выходной каталог проекта верхнего уровня из-за цепочки зависимостей.
Одной из моих проблем было и тестирование. Мне нравится сначала определять интерфейсы, а потом - реализацию. Поэтому, когда последующие реализации не завершены, я все еще могу запускать тесты. В этом помогают отдельные сборки. Мне нравится ваше мнение о расположении модуля. Меня беспокоит этот подход, так как дополнительные ссылки мне понадобятся в проекте верхнего уровня. Это может вызвать непреднамеренное использование нижних узлов. Вы бы порекомендовали сборку бутстрапа в таком случае?