Как читать значения конфигурации в сквозном проекте?

#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 .