DDD: Где сохранить доменные интерфейсы, инфраструктуру?
Имеет ли смысл группировать все интерфейсы вашего уровня домена (модули, модели, объекты, доменные службы и т.д.) на уровне инфраструктуры? Если нет, имеет ли смысл создавать "общий" проект/компонент, который группирует их все в общую библиотеку? В конце концов, определение "Уровень инфраструктуры" включает в себя "разделяемые библиотеки для слоев домена, приложения и интерфейса пользователя".
Я подумываю о разработке моей кодовой базы вокруг уровней DDD: пользовательский интерфейс, приложение, домен, инфраструктура. Это создало бы 4 проекта с уважением. Я хочу сказать, что вы ссылаетесь на уровень инфраструктуры на уровне домена. Но если вы определяете интерфейсы в проекте "Уровень домена", скажем, для IPost, тогда у вас будет ссылка на ссылку, когда вам нужно будет ссылаться на проект "Уровень домена" из проекта "Инфраструктура", когда вы определяете метод IPostRepository.Save(IPost post), Следовательно, идея "определить все интерфейсы в общей библиотеке".
Возможно, репозитории не должны ожидать сохранения объекта (IPostRepository.Save(IPost post), но вместо этого ожидайте параметры объекта (это может быть длинный набор параметров в Save()). Учитывая, это может быть идеальной ситуацией, которая показывает, когда объект становится слишком сложным, и дополнительные объекты Value должны быть рассмотрены в нем.
Мысли?
Ответы
Ответ 1
Эрик,
Я был в отъезде на пару, так что простите меня за ответ так поздно.
Что касается места размещения репозиториев, то лично я всегда помещаю репозитории в выделенный уровень инфраструктуры (например, MyApp.Data.Oracle), но объявляю интерфейсы, которым должны соответствовать репозитории на уровне домена.
В моих проектах уровень приложения должен получить доступ к уровню "Домен" и "Инфраструктура", поскольку он отвечает за настройку уровня домена и инфраструктуры.
Уровень приложения отвечает за внедрение соответствующей инфраструктуры в домен. Домен не знает, с какой инфраструктурой он разговаривает, он знает только, как назвать это. Конечно, я использую контейнеры IOC, такие как Structuremap, чтобы вставлять зависимости в домен.
Опять же, я не утверждаю, что именно так DDD рекомендует структурировать ваши проекты, просто так, я использую архитектуру своих приложений.
Приветствия.
Ответ 2
Im тихий новый в DDD, поэтому не стесняйтесь комментировать, если вы не согласны, так как вы здесь, чтобы учиться.
Лично я не понимаю, почему вам следует ссылаться на уровень инфраструктуры вашего домена. На мой взгляд, домен не должен зависеть от инфраструктуры. Объекты Domain должны быть полностью не осведомлены о том, на какой базе данных они работают или какой тип почтового сервера используется для отправки писем. Абстрагируя домен от инфраструктуры, его легче использовать; потому что домен не знает, на какой инфраструктуре он работает.
Что я делаю в своем коде, это ссылка на доменный слой из моего уровня инфраструктуры (но не наоборот). Репозитории знают объекты домена, потому что их роль заключается в сохранении состояния для домена. Мои репозитории содержат мои основные операции CRUD для моих корневых агрегатов (get (id), getall(), save (object), delete (object) и вызываются из моих контроллеров.
Что я сделал в своем последнем проекте (мой подход - это чисто DDD, но он работал очень хорошо) заключается в том, что я абстрагировал свои репозитории с интерфейсами. Корневые агрегаты должны были быть созданы путем передачи конкретного типа репозитория:
Корневой агрегат должен был быть создан через репозиторий с помощью метода Get (ID) или Create() в репозитории. Конкретный репозиторий, построивший объект, прошел сам, чтобы агрегат мог сохранить свое состояние и состояние своих дочерних объектов, но ничего не знал о конкретной реализации репозитория.
например:.
public class PostRepository:IPostRepository
{
...
public Post Create()
{
Post post=new Post(this);
dbContext.PostTable.Insert(post);
return post;
}
public Save(post)
{
Post exitingPost=GetPost(post.ID);
existingPost = post;
dbContext.SubmitChanges();
}
}
public class Post
{
private IPostRepository _repository
internal Post(IPostRepository repository)
{
_repository = repository;
}
...
Public Save()
{
_repository.Save(this);
}
}
Ответ 3
Я бы посоветовал вам рассмотреть Архитектура лука. Он отлично подходит для DDD. Идея заключается в том, что ваши интерфейсы репозитория расположены непосредственно на уровне домена и ссылки на объекты:
IPostRepository.Save(Post post)
Домен не обязательно должен знать о репозиториях.
Уровень инфраструктуры не привязан доменом или кем-либо еще и содержит конкретные реализации репозиториев среди других материалов, связанных с I/O. В этом случае общая библиотека с различными помощниками называется Application Core, и на нее может ссылаться любой.