Многие учебники по DDD, которые я изучал, в основном охватывают теорию. Все они имеют примеры элементарного кода (Pluralsight и аналогичные).
В Интернете также предпринимаются попытки нескольких людей создать учебники по DDD с EF. Если вы начнете их изучать ненадолго - вы быстро заметите, что они сильно отличаются друг от друга. Некоторые люди рекомендуют держать приложение минимальным и избегать введения дополнительных слоев, например, хранилища поверх EF , другие решительно генерируют дополнительные слои, часто даже нарушая SRP, внедряя DbContext
в Aggregate Roots.
Я ужасно извиняюсь, если задаю основанный на мнении вопрос, но ...
Когда дело доходит до практики - Entity Framework является одним из самых мощных и широко используемых ORM. К сожалению, вы не найдете исчерпывающего курса по DDD.
Важные аспекты:
Entity Framework выводит UoW & Repository (
DbSet
) из коробкис EF ваши модели имеют навигационные свойства
с EF все модели всегда доступны выключены
DbContext
(они представлены какDbSet
)
Ловушки:
Вы не можете гарантировать, что ваши дочерние модели будут затронуты только через Aggregate Root - ваши модели имеют свойства навигации, и их можно изменить и вызвать
dbContext.SaveChanges()
с помощью которого
DbContext
вы можете получить доступ к каждой модели, таким образом обойдя Aggregate Rootвы можете ограничить доступ к дочерним элементам корневого объекта с помощью метода
ModelBuilder
in , пометив их как поля - я до сих пор не верю, что это правильный путь для DDD, плюс трудно оценить, к каким приключениям это может привести в будущем ( довольно скептически )OnModelCreating
конфликты:
без реализации другого уровня репозитория, который возвращает Aggregate, мы не можем даже частично устранить вышеупомянутые ловушки
реализуя дополнительный уровень хранилища, мы игнорируем встроенные функции EF (каждый
DbSet
уже является репо) и усложняем приложение
Мой вывод:
Прошу прощения за мое невежество, но на основании приведенной выше информации - либо Entity Framework не подходит для доменно-управляемого дизайна, либо доменно-управляемый дизайн является несовершенным и устаревшим подходом.
Я подозреваю, что у каждого из подходов есть свои достоинства, но сейчас я совершенно потерян и не имею ни малейшего представления о том, как совместить EF с DDD.
Если я не прав - может кто-нибудь хотя бы подробно описать простой набор инструкций (или даже предоставить приличные примеры кода), как работать с DDD с EF, пожалуйста?
Ответы:
DDD и EF имеют мало общего между собой.
DDD - это концепция моделирования. Это означает думать о Домене, Бизнес-требованиях и моделировать их. Особенно в контексте объектной ориентации это означает создание дизайна, который отражает бизнес-функции и возможности.
EF - это технология постоянства. В основном это касается данных и записей базы данных.
Эти двое резко разведены. Конструкция DDD может использовать EF в некоторой форме под капотом, но эти два не должны взаимодействовать любым другим способом.
Некоторые интерпретации доменного дизайна на самом деле поддерживают моделирование данных, и я думаю, что это ваш вопрос. В этой интерпретации «сущности» и «объекты значений» по сути являются только бессистемными держателями данных, и проект касается самих себя, какими свойствами они обладают и как они связаны между собой. В этом контексте DDD против EF может подойти.
Эта интерпретация, однако, ошибочна, и я настоятельно рекомендую полностью ее игнорировать.
В заключение : DDD и EF не являются взаимоисключающими, они фактически не имеют отношения друг к другу, если вы выполняете правильное моделирование объектов, а не моделирование данных. Объекты DDD не должны быть в той или иной форме артефактами EF. Например, объекты DDD не должны быть EF-объектами. Внутри какой-либо бизнес-функции в проекте DDD может использоваться EF с некоторыми связанными объектами данных, но они всегда должны быть скрыты под бизнес-ориентированным интерфейсом, ориентированным на поведение.
источник
Рассматривайте EF как библиотеку доступа к данным, которая только немного более строго типизирована, чем необработанный ADO.NET. Я бы не рекомендовал моделировать свой домен с использованием классов сущностей EF, как я бы не рекомендовал моделировать домен с использованием необработанных DataSet или DataTable.
Я понимаю, что EF продается как ярлык между доступом к базе данных и моделированием домена, однако этот подход по своей сути несовершенен, поскольку решает две в основном не связанные с этим проблемы. В .NET были и другие попытки заставить класс выполнять какие-то совершенно не связанные вещи (например, .NET Remoting), но они не увенчались успехом.
Сделайте DDD, используя классы POCO и не позволяйте схеме базы данных управлять вашим дизайном. Держите EF внутри уровня хранилища / персистентности и не позволяйте объектам EF просачиваться наружу.
источник
Нет.
Абстракции Entity Framework были созданы с учетом ORM, а не DDD.
DbSet
Абстракции в любой версии Entity Framework далеко не в простоте DDD Repository - не говоря уже оDbContext
котором выставляет мильон вещь более UnitOfWork.Вот неисчерпывающий список элементов в резюме EF Core 2.1,
DbSet<TEntity>
который нам не нужен в DDD:Attach(TEntity)
и все его братья и сестрыFind(Object[])
Update(TEntity)
и все его братья и сестрыIQueryable
В дополнение к перетаскиванию ненужных зависимостей с ними, они затеняют замысел репозитория, который обычно демонстрирует очень простое поведение при сборе. Плюс неплотные абстракции - это постоянный соблазн для разработчиков слишком привязываться к EF и угроза разделению интересов.
Итог: вы должны обернуть этих толстяков в красивые, обтекаемые концепции и угадать, что это означает введение дополнительных классов.
Относительно убедительный пример того, что вы можете сделать с EF и DDD (хотя некоторые высказанные точки зрения спорны): https://kalele.io/blog-posts/modeling-aggregates-with-ddd-and-entity-framework/
Я действительно не вижу связи между двумя частями этого предложения. Независимо от подхода, в DDD есть вещь, называемая Службой приложений, и именно здесь вы манипулируете Единицей Работы / Хранилищем (или
DbContext
). Не в общих корнях.В то время как это могло бы быть правильным подходом, если бы это был образованный компромисс, недавняя антирепозитивная тенденция «минимализм Entity Framework» является бредовой. Он обвиняет шаблоны DDD в трении, которое происходит с Entity Framework, когда действительно создатели EF ничего не сделали для того, чтобы сделать их среду совместимой с лучшими практиками из коробки. Все это время они тесно связаны с этой самой средой со всеми проблемами с точки зрения безопасности кода и возможности сопровождения, которые могут возникнуть.
источник
Я использовал подход, при котором каждый Агрегат получает свой собственный DBContext, отображающий только то, что нужно для Агрегата. Я думаю, что это также было описано Джули Лерман.
Это сработало очень хорошо, но может быть недостаточно для более интересных моделей, где вы не хотите связывать свои концепции с вашими сущностями.
источник
Просто хотел бы поделиться возможным решением для рассмотрения:
избегать прямой ссылки на проект EF в Service Layer
создайте дополнительный слой репозитория (использует проект EF и возвращает Aggregate Root)
ссылка на слой репозитория в проекте уровня сервиса
Архитектура :
UI
Уровень контроллера
Сервисный уровень
Слой репозитория
Entity Framework
Основной проект (содержит модели EF)
Подводные камни, которые я вижу при таком подходе:
если репозиторий возвращает Aggregate Root не как дерево модели EF (например, мы возвращаем отображенный объект) - мы теряем способность EF отслеживать изменения
если Aggregate Root является моделью EF - все его навигационные свойства все еще доступны , хотя мы не можем иметь с ними дело
DbContext
(мы не ссылаемся на проект EF в Service Layer)источник