DDD-как я могу избежать пересечения границ агрегата здесь?
Мы работаем над новым проектом (переписываем существующее приложение), и у меня возникли проблемы с моей моделью домена / дизайном репозитория.
Вот (упрощенная) версия двух ключевых частей в нашей модели предметной области:
Как вы можете видеть, у меня есть абстрактная концепция поста , который может быть обзором, обсуждением, фотографией, видео и т. д. Сообщения также могут иметь комментарии.У меня также есть абстрактное понятие местоположения , которые являются очевидно, такие вещи, как улицы, города, кварталы и т. д.
Теперь это, естественно, выглядело для меня как два ясных агрегатных корня. Поэтому я создал два репозитория, один из которых называетсяPostRepository , а другой - LocationRepository .Все это прекрасно работало, я могу добавить/получить любой тип сообщения (или комментария) и добавить/получить любой тип местоположения через один из этих двух репозиториев.
Но теперь я в сценарии "посадочной страницы" для города (для образец).
На этой странице мне нужно в основном показать "все сообщения для этого местоположения".
Как это определяется? Ну, сообщение может быть (необязательно) помечено в определенном месте. Детали реализации, поэтому я не хочу слишком углубляться в данные (так как это не то, о чем идет речь в DDD), но по существу существует геопространственный интеллект, чтобы определить, какие сообщения содержатся в определенном местоположении с помощью файла формы местоположения и широты/долготы помеченного сообщения.
Но как я могу получить эту информацию, не пересекая границ?
Какой репозиторий я использую? Нужен ли мне новый?
Если это имеет значение (или для любопытных), это веб-приложение (ASP.NET MVC), с базой данных SQL Server 2008 и Entity Framework 4.0.
Если вам нужны какие-либо разъяснения, дайте мне знать.
EDIT
В настоящее время мы используем модифицированную версию шаблона спецификации для получения моделей предметной области.
Например, это код в нашем BLL, чтобы получить все отзывы, где оценка >= 4:
var reviews = postRepository // GenericRepository<Post>
.Find() // IQueryable<Post>
.OfType<Review>() // IQueryable<Review>
.Where(x => x.Score >= 4)
.ToList(); // List<Review>
Но теперь мне нужен такой код:
var reviews = postRepository
.Find()
.OfType<Review>()
.Where( //lat long, or Locations FK )
.ToList();
Проблема в том, что я не знаю, как выполнить вышеприведенный запрос без добавления промежуточной сущности join (LocationPost-поскольку это много ко многим) и добавить FK к модели домена Post.
Но делая это, я пересекаю границы совокупности-не так ли?3 ответа:
Я бы привязал запись к местоположению во время создания, чтобы для каждого местоположения я мог получить (через репозиторий) список связанных записей. Это выглядело бы так:
Создание:
var p = new Post(latitude, longitude); var locations = locationRepository.FindByCoordinates(latitude, longitude); foreach (var l in locations) { l.AssociatePost(p); } session.Save(p);
Извлечение:
var associatedPosts = postRepository.FindByLocation(locationId); foreach (var p in associatedPosts) { Display(p); }
Под капотом связь между должностями и местоположением будет реализована в виде отношения таблицы "многие ко многим". Существует одна проблема с этим решением: добавление нового местоположения требует сканирования всех записей и назначения их новому местоположению (если применимый).
Надеюсь, что помогает.
Почему это проблема? Согласно Эвансу в его книге, один AR может очень хорошо ссылаться на другой AR. (Однако вы не можете ссылаться на дочерний элемент в AR из другого AR)
Кроме того, действительно ли местоположения являются агрегатными корнями? Определение агрегатного корня состоит в том, что он действует как граница консистенции. Соответствует ли это определению местоположения? Я бы сказал, что местоположение-это ценный объект.
Здесь есть в значительной степени два лагеря относительно репозиториев и AR ассоциации:
Тот, который говорит, что все агрегатные корни должны быть извлечены через их соответствующий репозиторий, и AR должны использовать мягкие отношения, например ID между ними
И тот, который говорит, что агрегатные корни могут очень хорошо получать другие связанные агрегатные корни и что хранилище-это просто способ найти агрегатные корни.