Is it a reasonable pattern to use shared GUIDs as aggregate IDs for root aggregates that have a one-to-one relationship?
I'm not immediately seeing any reason not to other than clarity.
For example, I have an Organization Membership bounded context whose core-concern aggregate root is a Member. A Member aggregate holds membership related data, and references to the related Person aggregate (holds name, birthdate, etc.) and to the website User (EF Identity) aggregate.
My initial idea was to do something like this, where each aggregate root contains references to the related aggregate roots:
public class Member : AggregateRoot
{
Guid Id; // (Each aggregate ID is inherited)
Guid PersonId;
}
public class Person : AggregateRoot
{
Guid Id;
Guid UserId;
}
public class User : IdentityUser, IAggregateRoot
{
Guid Id;
}
Getting a Member's Person is the done with:
var person = personRepository.GetById(member.PersonId);
It then occurred to me that I could "simplify" things if I just used the same ID across Member, Person and Username, then retrieve related aggregates using, for example:
var person = personRepository.GetById(member.Id)
It's only a minor difference and I was initially pleased with the idea but am now becoming wary. Is this a bad idea as it obscures the relationship?
You could do that but you would be making the explicit implicit which is a bad thing. The fact that those entities use the same ID will be hidden, only in the Application services will this knowlege be found. This kinda feels like domain knowledge is leaking outside. Also, the relation between bounded contexts is hidden, you will not know what is upstream and what is downstream. The temporal dependency is also lost: what is created first, a Person
or a User
?
If you need to learn about this just search on your prefered search engine for "make the implicit explicit software development". Just in case your results are different you should read this.
P.S. sharing the same value for all entities is not bad.