4

I'm trying to fit users, roles and permissions into ddd. Currently I have a situation: 1. There are Permissions and Roles and Users that lives separately. They can live without any connections 2. User can have Role assigned and with role, he gathers linked Permissions

I have problem with defining aggregate root in this case. Roles and Permissions can be managed separately, so User can't be an aggregate for them. Role can be assigned to User (or reverse), but user is not a part of role, because can live without any role.

At any time, Permission can be assigned to role (many to many) or role can be assigned to user (many to many) but one user can't have same role assigned twice.

Some rules for my domain: Only Aggregate root can have list of events that will be dispatched Only aggregate root can have repository

What I have now

 public class Role : AggregateRoot<int>
 {
    public string Code { get; protected set; }

    public string Name { get; protected set; }

    public static Role Create(string name, string code) => new Role(name, code);

    public Role Modify(string name, string code)
    {
        this.Name = name;
        this.Code = code;
        return this;
    }

    protected Role(string name, string code)
    {
        this.Name = name;
        this.Code = code;
    }

    protected Role()
    {

    }
}

public class Permission : AggregateRoot<int>
{ 
    public string Code { get; protected set; }

    public string Name { get; protected set; }

    public static Permission Create(string name, string code) 
        => new Permission(name, code);

    public Permission Modify(string name, string code)
    {
        this.Name = name;
        this.Code = code;
        return this;
    }

    protected Permission(string name, string code)
    {
        this.Name = name;
        this.Code = code;
    }

    protected Permission()
    {

    }
}
 public class User : AggregateRoot<int>
{
    public string Name { get; protected set; }

    public static User Create(string name) => new User(name);

    public virtual ICollection<Credential> Credentials { get; set; }

    protected User(string name)
    {
        this.Name = name;
    }

    protected User()
    {

    }
}

With this approach I can manage All separately because all are aggregate roots for themselves. If I'd like to assign Role to a user, probably I'd have to create domain service (access to different roots) or throw event and handle it creating a link. This feel rather bad. Other idea is to treat user, role and permission as entity, create Aggregate root that won't be persisted on db and do all manipulations there. Con for this idea: Repository for aggregate root would need to manipulate with repositories for entities.

Do you have any idea how this should be defined?

Liarus
  • 49
  • 1
  • 3
  • 2
    Is Authorization your core domain? if not then you don't have to use DDD for that, don't make things complex unnecessarily. – msmani Apr 18 '18 at 04:48
  • It's not a direct answer but you can have a look here: https://stackoverflow.com/questions/50597171/can-aggregate-root-reference-another-root/50618538#50618538 TL;DR You can make 3 different namespaces with 3 sets of all 3 classes. Let every set represent a different context. Each set of classes only need to contain the bare minimum required to perform the required action. Your question already implies several different contexts, eg. System configuration (role + permission) and Access management (users + roles) – Reasurria Jun 20 '23 at 13:06

0 Answers0