0

I am new at domain driven design, and want to learn some about aggregates. For example I have a User and Role entities.

public class User {
    public string Id {get; set;}
    public string Username {get; set;}
    public IEnumerable<Role> Roles {get; set;}
}

public class Role {
   public string Id{get; set;}
   public string Name {get; set;}
}

In this stuation, User is an aggregate root. Roles are part of user. But If I want to use Many-to-many relations with Role and User, how changes the aggregation? In this stuation which is the aggregate root?

  • 1
    It doesn't; it's still an aggregate root. Keep in mind that DDD is fundamentally a design technique, not a coding technique. – Robert Harvey Nov 25 '19 at 14:25
5

Just because you have a many to many relationship at a data or database level, doesn't mean it has to be represented in code. You should model for the relationships you care about or are useful to you. The relationship of roles to users is more of an implementation detail and not something worth modelling at all at a code level, let the database handle the consistency. Knowing all the users in a role seems like more of a user search capability than anything useful in working with a role.

In either case you really don't want to model both directions of a many to many case in code at the same time, because you will run into circular reference and consistency issues. Databases are designed to handle that consistency gracefully, let them do the hard work and only model the relationship in one direction at a time in code. Chances are your users are really only interested in one direction of such relationships at a time anyway.

  • plus1. From hard won experience, do not mix your domain (business) model with the relational data design. First you want to keep these things decoupled and second, a relational DB engine will be warp factors faster than mere code. – radarbob Nov 26 '19 at 2:07
1

In this stuation, User is an aggregate root. Roles are part of user. But If I want to use Many-to-many relations with Role and User, how changes the aggregation? In this stuation which is the aggregate root?

Aggregates don't share entities.

Which means, if "Role" is a thing that changes over time, then each instance of role will belong to one and only one aggregate.

If role entities aren't shared, then having them as part of the same aggregate as the user entity is fine.

If role entities are shared, then what normally happens is identifier values are used to describe the relationships. In other words, the join table gets a representation in your domain model.

Depending on your design, it could make sense for the join table to belong to User or to role. It could also be that the join table is an aggregate of its own (the relationship between user and role being a thing that has a life cycle of its own, possibly with its own rules).

-1

The many-to-many association would make the Role independent of specific User both for the external reference and for changes. The design should therefore not put them each in their own aggregate:

AGGREGATE A cluster of associated objects that are treated as a unit for the purpose of data changes. External references are restricted to one member of the AGGREGATE, designated as the root.

Your implementation could still have a collection in the User entity, to represent the association. It would refer to a set of unique Role either via object reference or reference by id, which could be found back in a repository. The same reference could appear in collections of several Users, thus allowing for many-to-many.

Note: this implementation would provide for many to many association, but one way navigability only. For bidirectional navigation, you'd need also a Users collection in the Role entity. But other approaches exist as well.

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.