I am trying to learn DDD. I am modeling a property management domain and I think I have two contexts (subdomains?): a property management context and a resident context.
Let's say I have an aggregate root Apartment
, that holds Floorplan
s and Unit
s. Each Apartment
can have many Floorplans
, and each Floorplan
can have many Unit
s.
public class Apartment : IAggregateRoot // for clarity
{
public int Id { get; }
public Address Address { get; set; }
public ICollection<Floorplan> Floorplans { get; set; }
}
public class Floorplan
{
public int Id { get; }
public int ApartmentId { get; set; }
public string Name { get; set; }
public int Bedrooms { get; set; }
public int Bathrooms { get; set; }
public ICollection<Unit> Units { get; set; }
}
public class Unit
{
public int Id { get; }
public int FloorplanId { get; set; }
public string Number { get; set; }
}
Let's say in the property management context I now introduce a Resident
who gets assigned to a Unit
. My Unit
and Resident
class now looks like this:
public class Unit
{
public int Id { get; }
public int FloorplanId { get; set; }
public string Number { get; set; }
public ICollection<Resident> Residents { get; set; }
}
public class Resident // in the property management context
{
public int Id { get; }
public string FirstName { get; set; }
public string LastName { get; set; }
public void UpdateBalance(...);
}
My question is now if I introduce a Resident
in the resident context (that can PayRent()
or UpdateProfile()
, etc) they must be have a 1:1 relationship with Resident
in the property management context, but I thought I cannot reference a non-aggregate root entity without going all the way through Apartment
because a Resident cannot exist without an Apartment.
Is my understanding of aggregate roots incorrect? Is Resident an aggregate root in both contexts? I'm not sure how that would be modeled.
Apartment
class (as presented in your question) is not acting like an aggregate root - in that it's just a tree of objects, and that's not the same thing; it doesn't encapsulate what's within the aggregate, and it doesn't provide an interface to support operations on the aggregate. So it's not a DDD aggregate, even though it's designated as one, which makes other considerations superfluous, because they don't really give you any benefits if you don't have a proper aggregate root.