Из вашего вопроса мне не ясно, как должно выглядеть ваше приложение и какова его цель.Что ты моделируешь?Можете ли вы предоставить более подробную информацию поставщику?
Насколько я понимаю, ваши сущности: Арендатор , OrganizationalUnit и Пользователь .
Каковы отношения между Арендатором и OrganizationalUnit ?Кажется, что Арендатор должен содержать много OrganizationalUnit s, но какова цель OrganizationalUnit ?Нужно ли группировать и организовывать пользователей (например, при работе в определенных командах или в составе отдельных подразделений компании (разработка, продажи, дизайн и т. Д.)?
Первое, чтолюди сталкиваются, когда начинают с DDD: агрегаты . Они являются наиболее неправильно понятым понятием и их трудно понять. Я думаю, что, когда человек начинает моделировать приложения, он / она не должен начинать с попытки определить Агрегаты . Начните с определения сущностей и выяснения отношений между ними. После этого проанализируйте свое приложение и технические проблемы, которые у него возникнут, и подумайте, как вы можете организовать свои сущности в Агрегаты чтобы решить эти проблемы.
Вы читали книгу DDD Эрика Эванса ? Если нет, я настоятельно рекомендую ее.
Как образец Агрегаты используются для решения пары проблем (это не полный список):
Определение транзакцийГраницы изменений в ваших сущностях.Какие сущности должны изменяться вместе в целом и какие сущности могут меняться независимо друг от друга?Большинство современных приложений являются многопользовательскими, поэтому у вас могут быть параллельные операции (например, добавление нескольких пользователей одновременно в OrganizationalUnit из разных администраторов )
Ограничьте количество ссылок, которые одна сущность имеет на другие сущности, поэтому, когда вы загружаете их из базы данных, вы не загружаете одну сущность с коллекцией, которая содержит 1 000 0000 других сущностей, которые могут вызвать ваш серверисчерпать память и сбой.Это не очень практично и не сработает.
Уточнить пути обхода.Двунаправленные ассоциации трудно поддерживать.Например, у вас может быть Пользователь , принадлежащий Подразделению , и OgranizationalUnit содержит много Пользователей , поэтому у вас много-много связей,Загрузка одного пользователя со всеми OrganizationalUnits и загрузка всех других пользователей , принадлежащих к этим OrganizationalUnits , просто чтобы изменить имя этого Пользователь не очень практичен.
Вот где Хранилища могут помочь.Если вы хотите получить OrganizationalUnits для определенного пользователя , у вас будет OrganizationUnitRepository с getOrganizationalUnitsForUser (userID) .Если вы хотите найти Users для OrganizationalUnit , у вас будет UserRepository с getUsersForOrganizationalUnit (unitID) методом.Таким образом, вы будете использовать Репозитории для прохождения отношений между сущностями, организованными в агрегаты.
Начните с определения сущностей сначала с их взаимосвязей, проанализируйте проблемы вашего приложения, а затем упорядочите их по совокупностина проблемы, которые у вас есть (рефакторинг позже, если вы не понимаете это правильно).
В вашем случае вы можете:
Все объекты должны быть частью отдельныхагрегаты и каждая сущность должна быть корнем его агрегата.Есть репозитории для всех из них.В ваших Сервисах вы будете использовать Репозитории для извлечения нескольких сущностей, если они вам нужны для конкретной операции.
Если вы не думаете, что Арендатор будет иметь тысячи OgranizationalUnits , вы можете включить его в Арендатор Агрегировать и загрузить их все вместе. В этом случае, поскольку OgranizationalUnits являются иерархическими, вам придется загружать родительский и дочерний элементы вместе. Если вы не хотите этого, используйте ReferenceByID и имейте свойство с parentID только для каждого OgranizationalUnit вместо загрузки коллекции потомков и родителя.
Одна проблема с распределением сущностей по различным агрегатам - это граница согласованности. Таким образом, вы должны ввести конечную согласованность между различными агрегатами, и будет сложнее применить некоторые правила.
Например, допустим, у вас есть ограничение на количество пользователей , которые могут быть частью Арендатора . Если сущность Арендатор и сущность OrganizationalUnit являются частью одной совокупности, то они находятся в одной границе согласованности. Таким образом, вы загрузите агрегат, сделаете проверку и, если она нарушена, выдаст ошибку, если не добавите Пользователь и сохраните агрегат. В случае многопользовательского сценария, если два администратора загружают один и тот же агрегат и каждый добавляет пользователя к OrganizationalUnit , во время сохранения вы можете использовать Оптимистичный параллелизм для разрешения конфликтов, чтобы вы не получили счет Users , превышающий ограничение.
Если разбить совокупность на две части, они окажутся в разных границах согласованности, и соблюдение этого правила станет более сложным. Это называется Проверка на основе набора . Вы можете искать информацию на эту тему, но это трудно найти, поэтому я не могу указать нигде .. извините за это.
Если у вас есть такие проблемы с проверкой набора, и вы можете использовать кластеризацию без проблем с производительностью при загрузке, то сделайте это и не делайте Проверка на основе набора
Для более подробной информации вы можете проверить Эффективный совокупный дизайн . Здесь обсуждаются эти проблемы и решения в деталях. Он на самом деле имеет Арендатор часть своей модели тоже:)