#domain-driven-design
#дизайн, управляемый доменом
Вопрос:
Я следовал рекомендациям DDD для структурирования своего проекта, у меня есть уровни домена, инфраструктуры, приложений и презентаций.
Я также определил сквозной проект под названием Common. Все остальные проекты зависят от Common.
Одна из вещей, которые мне нужны в общем проекте, — это мои значения конфигурации / настройки. Я определил все параметры решения в таблице БД. Общий проект считывает настройки, и любой другой проект может получить доступ к этим настройкам через общий проект…
Как общий проект должен получить доступ к БД? В любом другом месте решения я использую уровень инфраструктуры для чтения из БД, но если я буду ссылаться на инфраструктуру в общем проекте, я получу циклическую зависимость.
Должен ли общий проект иметь собственный считыватель БД? Или помещение всей конфигурации в общий проект изначально не было правильным дизайном?
Комментарии:
1. Какая конфигурация / настройки? Связаны ли эти приложения (например, кэширование, конечные точки, строки подключения, IoC и т. Д.) Или связаны с demain?
2. @plalx: спасибо за ваш ответ. Это конфигурации для всего решения, которые не являются конфиденциальными и могут храниться в виде обычного текста (поэтому не строка подключения)… В основном это значения конфигурации, которые могут меняться в зависимости от того, в какой стране запущено приложение: например, Rent_Unit (может быть в неделю или в месяц) Или название страны (например, Новая Зеландия, Великобритания, …) также некоторые минимальные и максимальные ограничения для свойств, например, максимальная длина для пользователяПрофиль в символах… Также некоторая конечная точка, которая может быть сохранена в виде обычного текста.
Ответ №1:
common
Пакет может быть организован по функциям. Здесь IConfigProvider
реализации будут находиться в том же пакете, что и интерфейс.
Например.
Вы также можете рассмотреть глобальную конфигурацию как вспомогательный BC и реализовать соответствующий уровень защиты от коррупции в каждом последующем контексте, где каждый контекст имеет свое собственное представление и интерпретацию такой конфигурации.
Комментарии:
1. Большое спасибо. Извините, я не понимаю, не могли бы вы объяснить следующие вопросы… итак, ConfigProvider живет в общем проекте, поэтому я предполагаю, что у него должен быть собственный DbReader для чтения значения конфигурации из БД? Не могли бы вы объяснить, почему domian.model находится внутри общего проекта? в
Entity
какой структуре мы храним значения конфигурации?2. @HoomanBahreini
domain.model
не имеет никакого отношения к вашему варианту использования. Я просто хотел показать, чтоcommon
это вспомогательная библиотека, которая может поддерживать множество разных уровней. Например, у вас может быть базовыйEntity
класс вcommon.domain.model
, от которого наследуются сущности во всех других BCS. В моем приведенном выше примереDbReader
это будет реализацияIConfigProvider
и да, она может находиться вcommon.config
пакете, как в примере.
Ответ №2:
Зависимости — это всегда интересная вещь.
Поскольку вы не указали, какие языки / среды вы используете, и у меня есть опыт работы с C #, я буду использовать методы и терминологию, связанные со строгими типизированными OO-языками, подобными этому.
Допустим, мы разделим интерфейс и реализацию. Я буду использовать нотацию c #, в которой интерфейс начинается с заглавной буквы «I», чтобы было более понятно, что такое интерфейс.
Ваши репозитории являются частью вашего домена. Допустим, у вас есть объект Account и у вас есть AccountRepository для этого объекта.
Что мы сделаем, так это отделим интерфейс для этого репозитория от его реализации. У нас будет IAccountRepository и конкретная реализация (возможно, более одной, но это очень редко) для нее: AccountRepository.
Если мы хотим использовать базу данных SQL, у нас может быть SQLAccountRepository. Если мы хотим использовать MongoDB, у нас может быть MongoDBRepository. Оба этих конкретных репозитория будут реализовывать интерфейс IAccountRepository.
IAccountRepository является частью вашего домена, Но реализации (SQL, MongoDB и т. Д.) Являются Частью вашего уровня инфраструктуры, Поскольку они будут обращаться к внешним вещам (SQL server или MongoDB server в этом примере).
В этом случае вашими зависимостями будут «Инфраструктура -> Домен«, а не «Домен -> Инфраструктура«. Это изолирует ваш домен от инфраструктуры, поскольку инфраструктура имеет ссылку на примечание домена наоборот.
Используя интерфейсы, ваш домен указывает только то, что ему нужно, а не то, как ему это нужно.
Если вы примените ту же идею, вы можете определить интерфейсы в своем общем проекте для получения (и настройки, если необходимо) параметров (ISettingsProvider, IApplicationSettings и т. Д.) И Разрешить инфраструктуре, которая ссылается на Common, Предоставлять реализацию для этих интерфейсов (SQLSettingsProvider и т. Д.)
Вы можете использовать внедрение зависимостей, поиск служб или аналогичный метод для привязки реализаций к интерфейсам.
Комментарии:
1. Я бы подумал, что репозитории являются частью инфраструктуры… но в любом случае, если я буду ссылаться на репозитории из сквозного проекта, я получу циклическую зависимость.
2. Почему вы ссылаетесь на репозитории из сквозного проекта? Если репозитории являются частью вашего домена, на них будут ссылаться только с уровня приложений и инфраструктуры. Инфраструктура будет включать сквозной проект и реализацию поставщика. Вот диаграмма, которая показывает, как внешние слои ссылаются на внутренние слои. shawnjlee. files.wordpress.com/2015/09/onion1.png .