Может ли не агрегатный корень содержать ссылку на другой не агрегатный корень? - PullRequest
0 голосов
/ 08 сентября 2018

Если у меня есть two aggregates, как это:

Первый агрегат:

  • WorktimeRegulation (Root)
  • Worktime
  • Регламент зачисления

Пояснения с данными:

WorktimeRegulation:

 public class WorkTimeRegulation : Entity<Guid>, IAggregateRoot
    {
        private WorkTimeRegulation()//COMB
       : base(Provider.Sql.Create()) // required for EF
        {
        }
        private WorkTimeRegulation(Guid id) : base(id)
        {
            _assignedWorkingTimes = new List<WorkingTime>();
            _enrolledParties = new List<RegulationEnrolment>();
        }
        private readonly List<WorkingTime> _assignedWorkingTimes;
        private readonly List<RegulationEnrolment> _enrolledParties;
        public string Name { get; private set; }
        public byte NumberOfAvailableRotations { get; private set; }
        public bool IsActive { get; private set; }
        public virtual IEnumerable<WorkingTime> AssignedWorkingTimes { get => _assignedWorkingTimes; }
       public virtual IEnumerable<RegulationEnrolment> EnrolledParties { get => _enrolledParties; }
        //...
    }

Id|    Name            |   NumberOfAvailableRotations|  IsActive 

 1|    General Rule    |          2                  |    true   

Время работы:

public class WorkTime : Entity<Guid>
    {
        private WorkTime()
      : base(Provider.Sql.Create()) // required for EF
        {
        }
        private WorkTime(Guid id) : base(id)
        {
            ActivatedWorkingTimes = new List<WorkingTimeActivation>();
        }
        private ICollection<WorkingTimeActivation> _activatedWorkingTimes;

        public string Name { get; set; }
        public byte NumberOfHours { get; set; }
        public byte NumberOfShortDays { get; set; }
        public Guid WorkTimeRegulationId { get; private set; }
        public virtual ICollection<WorkingTimeActivation> ActivatedWorkingTimes { get => _activatedWorkingTimes; private set => _activatedWorkingTimes = value; }
        //....
   }

Id|  Name   |   NumberOfHours| NumberOfShortDays |WorkTimeRegulationId 

1 | Winter  |     8          |    1              |    1
2 | Summer  |     6          |    0              |    1

Второй агрегат:

  • Shift (Root)
  • ShiftDetail
  • ShiftEnrolment

Уточнение с данными:

Сдвиг:

  public class Shift : Entity<Guid>, IAggregateRoot
    {
        private readonly List<ShiftDetail> _assignedShiftDetails;
        private readonly List<ShiftEnrolment> _enrolledParties;


        public string Name { get; set; }
        public ShiftType ShiftType { get; set; }
        public int WorkTimeRegulationId { get; set; }
        public bool IsDefault { get; set; }
        public virtual WorkingTimeRegulation WorkTimeRegulation { get; set; }
        public virtual IEnumerable<ShiftDetail> AssignedShiftDetails { get => _assignedShiftDetails; }
        public virtual IEnumerable<ShiftEnrolment> EnrolledParties { get => _enrolledParties; }
        //...........
   }

Id|  Name      |  ShiftType  |  WorkTimeRegulationId  | IsDefault 
1 | IT shift   |  Morning    |    1                   |  1 

ShiftDetail:

  public class ShiftDetail : Entity<Guid>
    {
        public Guid ShiftId { get; private set; }
        public Guid WorkTimeId { get; private set; }
        public DateTimeRange ShiftTimeRange { get; private set; }
        public TimeSpan GracePeriodStart { get; private set; }
        public TimeSpan GracePeriodEnd { get; private set; }
        public virtual WorkTime WorkTime { get; private set; }

        private ShiftDetail()
        : base(Provider.Sql.Create()) // required for EF
        {
        }
        //..........
   }

ShiftId  WorkTimeId shift-start  shift-end   
  1          1        08:00        16:00
  1          2        08:00        14:00

Мои вопросы здесь:

  • Можно ли хранить ссылку на неагрегированный корень (ShiftDetail) для другого неагрегированного корня (WorkTime)?
  • Эксперт в области уточняет, что: должен иметь shift detail для каждого worktime, связанного с специфический worktimeRegulation. И не может обновить количество рабочих часов в worktime, если есть ссылка в shiftDetails. Предыдущий пример показывает, что мы есть two worktimes(winter,summer), поэтому у нас есть shiftdetai л для winter придерживаться 8 рабочих часов и shiftdetail для summer придерживаться 6 рабочих часов. Теперь я чувствую, что инвариант деталей сдвига контролируется неагрегированным корнем (worktime) Как заставить этот инвариант?

  • Согласно предыдущей информации, могу ли я сделать ошибку, связанную со спецификациями агрегатов?

1 Ответ

0 голосов
/ 08 сентября 2018

Допустимо ли для неагрегированного корня (ShiftDetail) хранить ссылку на другой неагрегированный корень (WorkTime)?

Нет, если они не существуют в одном агрегате.

Вы можете хранить ссылки только на другие идентификаторы Агрегированного корня.

Вы можете хранить ссылку на идентификатор вложенной сущности из другого Агрегата, но вы должны помнить, что этот идентификатор непрозрачен, вы не можете предполагать, что он используется внутренне корневым объектом Агрегата для поиска вложенной сущности.

Теперь я чувствую, что инвариант деталей сдвига контролируется неагрегированным корнем (рабочее время). Как заставить этот инвариант?

Вы можете применить инвариант двумя способами:

  1. Внутри агрегата. Это означает, что Агрегат должен быть достаточно большим, он должен владеть всем необходимым государством. Это исполнение строго соответствует.

  2. Координируется Saga / Process Manager. Этот компонент реагирует на изменения внутри возможных нескольких агрегатов и отправляет команды другим агрегатам. Сага является противоположностью совокупности. Это исполнение в конечном итоге соответствует.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...