0

Is changing the domain according to the user privilege on specific fields considered as anti-pattern?

My case:

I have Schedule Entity (aggregate root) like this:

public class Schedule : Entity<Guid>, IAggregateRoot
    {
        private Schedule()
     : base(Provider.Sql.Create()) // required for EF
        {
        }

        public Schedule(Guid id, string name, int workingSystemId, ScheduleType scheduleType) : base(id)
        {
            Name = name;
            WorkingSystemId = workingSystemId ;
            ScheduleType = scheduleType;
            _assignedWeeks = new List<ScheduleDetail>();
            _enrolledParties = new List<ScheduleEnrolment>();
            MaxNumOfInstances = 300;
            NumOfInstances = IsFixed ? 1 : 2;
        }
        private readonly List<ScheduleDetail> _assignedWeeks;
        private readonly List<ScheduleEnrolment> _enrolledParties;

        public string Name { get; set; }
        public int WorkingSystemId { get; set; }
        public ScheduleType ScheduleType { get; set; }
        public int NumOfInstances { get; set; }
        public int MaxNumOfInstances { get; }
        public bool IsDefault { get; set; }
        public bool IsFixed
        {
            get
            {
                return ScheduleType != null && ScheduleType.HasFlag(ScheduleType.Fixed);
            }
        }
        public bool IsFlexible
        {
            get
            {
                return
                    ScheduleType != null && ScheduleType.HasFlag(ScheduleType.Flexible);
            }
        }
        public bool IsFullTime
        {
            get
            {
                return
                    ScheduleType != null && ScheduleType.HasFlag(ScheduleType.FullTime);
            }
        }
        public virtual IEnumerable<ScheduleDetail> AssignedWeeks { get => _assignedWeeks; }
        public virtual IEnumerable<ScheduleEnrolment> EnrolledParties { get => _enrolledParties; }
        public virtual WorkingSystem WorkingSystem{ get; set; }
}

Now the domain expert explains that we have to give him the ability to set WeekStart for example (the week start in this schedule is: Sunday), and NumberOfWeekends for example (NumberOfWeekends in this schedule is: 2). And these two critical fields are available only to set through role A. but the creation of schedules are available for role A & B and must set these fields during schedule creation!

Is creating another Entity and name it WorkingSystem considered as bad decision :

public class WorkingSystem : Entity<Guid>, IAggregateRoot
    {
        private WorkingGroup()//COMB
       : base(Provider.Sql.Create()) // required for EF
        {
        }
        public WorkingGroup(Guid id) : base(id)
        {
            _assignedWorkingTimes = new List<WorkingTime>();
        }

        private readonly ICollection<WorkingTime> _assignedWorkingTimes;

        public string Name { get; private set; }
        public byte NumberOfRotations { get; private set; }
        public Week WeekStart { get; private set; }
        public bool IsActive { get; private set; }
        public bool IsDefault { get; private set; }
        public byte NumberOfWeekends { get; private set; }
        public virtual ICollection<WorkingTime> AssignedWorkingTimes { get => _assignedWorkingTimes; }
 }

Now the creation of this Entity is avaliable only for role A.

How to solve this problem ?

3

Authorization (only users with "Role A" can do this) and business logic (setting WeekStart and NumberOfWeeks) are separate concerns. Your domain model should provide methods that alter the state of the model in valid ways. That includes a method that someone with Role A should only be calling.

It is up to the application layer or use case layer to determine which methods on the domain model should be called.

Upon creation of a Schedule, you'll need a WeekStart and NumberOfWeeks. This should be handled by a constructor on the class. There must be a default value for these properties, so write a constructor that does not allow you to pass those two values in, and instead sets them to the default values that "Role B" users would need.

If a "Role A" user creates a schedule, they can specify the WeekStart and NumberOfWeeks, so create another constructor allowing you to pass those values in.

Again, the application or use case layers need to pick the correct constructor according to the roles the user has.

  • Then the existence of WorkingSystem is useless in this case ? – Anyname Donotcare Sep 1 '18 at 13:55
  • But how could we overcome the problem of (that these properties must have a value at the creation of schedule to make schedule entity in a valid state and role B can create Schedule at the same time?) – Anyname Donotcare Sep 1 '18 at 13:58
  • @AnynameDonotcare: I've updated my answer. – Greg Burghardt Sep 1 '18 at 14:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.