Ответ 1
Вы находитесь на правильном пути DDD в зависимости от того, насколько тонкий/толстый слой домена и сервиса. DDD говорит, что знание (то есть бизнес-логика) должно быть свернуто в модель домена. Перемещение проблем доступа к данным в DAL соответствует DDD, но я думаю, что перемещение бизнес-логики на уровень обслуживания не является. Если у вас тонкий слой "данных" домена (в основном для сущностей) и толстый уровень услуг (в основном для "бизнес-логики" ), у вас может быть анемичный домен.
Кроме того, в DDD нет технического уровня "Service Layer". Может существовать "уровень приложения", но он должен быть тонким и отвечать только за поток приложений/управление временем жизни класса домена. Это, по сути, то, что делают контроллеры в .NET MVC, управляют потоком приложений в контексте веб-http.
Если заполнение всей логики в Модели сделало ваш код чрезмерно сложным, мне было бы интересно услышать примеры того, что вы подразумеваете под "чрезмерно сложным". Вы можете правильно моделировать сложный домен, или есть шансы, что вы могли бы пойти на шаблоны DDD, чтобы скомпрометировать вещи. Я бы сказал, как вы указали это в своем вопросе, арка не DDD. Я бы просто назвал это "Слоистая архитектура", но это потому, что я предпочитаю использовать термин "уровень" только при разговоре о физической дуге. Однако ваша логическая архитектура является многоуровневой.
Мне очень нравится, что Дарин связался с Луковой аркой в своем ответе. Я становлюсь большим поклонником этого, и я нахожу его не эксклюзивным для DDD вообще. Если ваш код использует инъекцию зависимостей для решения зависимостей интерфейса с реализацией исполнения, у вас может быть форма луковой арки. Например, вы определяете какие-либо интерфейсы в своем DAL? Реализованы ли реализации этих интерфейсов во время выполнения?
Вот пример арки, которую я начинаю использовать в своих новых проектах. Это комбинация лука + DDD:
-
API
Проект/сборка: общие интерфейсы, перечисления, классы и методы расширения, используемые всеми другими слоями. Не нужно отдельно от домена, но может. -
Domain
Проект/сборка: все объекты и бизнес-логика. Зависит только отAPI
. Использует шаблоны DDD, такие как factory, сервис, спецификация, репозиторий и т.д. Также содержит больше доменных интерфейсов, которые не определены в API. -
Impl
Проект/сборка: реализация интерфейсов, определенных вAPI
иDomain
. Здесь внедряется EF DbContext, а также такие вещи, как ведение журнала, отправка электронной почты и т.д. Все эти реализации вносятся в зависимость, поэтому технически вы можете иметь несколько проектов/сборок Impl. -
UI
Проект/сборка: это проект MVC. Контроллеры непосредственно используют поверхность домена и не проходят через прикладной или служебный уровень. Любые зависимости интерфейса на фабриках, сервисах, репозиториях и т.д. Вводятся в домен контроллером с использованием MVC IoC (впрыск конструктора).
Я разместил слой API в самом ядре, но вы могли бы объединить проекты API и домена в один. В любом случае, большая мясистая часть лука - это Домен, и он имеет внутреннее наслаивание. Например, Сервисы могут зависеть от Заводов, которые зависят от Репозиториев, которые зависят от Сущностей.
Проект Impl - это то, что вы видите как "Инфраструктура" луковой кожи на диаграмме Палермо. Он находится на внешнем крае вместе с пользовательским интерфейсом и не содержит знаний о домене. Он знает, как отправлять электронную почту, хранить/извлекать данные с помощью EF и т.д. Если вы хотите, вы можете иметь более одного из них - например, 1 Impl для доступа к данным, 1 Impl для работы с почтой и т.д.
MVC имеет контроллеры и представления и концентрируется на потоке пользовательского интерфейса и веб-приложения. Все, что требует знаний о домене, передается домену, а классы классов - это конструктор, вводимый в контроллер. Это означает, что любые интерфейсы, введенные конструктором в классах доменов, автоматически разрешаются контейнером IoC.
Как последнее замечание, программирование против интерфейсов, определенных в классах API и домена, означает, что вы можете unit test проект домена отдельно от проекта MVC.