I am currently developing a DDD application and am confused about how to handle a scenario where it seems as if I have to access an aggregate root from another aggregate root. Here is an overview of my boundary contexts:
Users can join the site and create posts on topics they are interested in. They can also create groups and make posts specific to the group(s) they create or posts for all site members to see. Users can also upload a photo for their profile page for other to see or upload word documents and pdf files to associate with a post. A user can allow other user to join their group or make group invite only.
User (represents a member of the site)
Posts(a user can create many posts)
File(a user can associate an image to appear on their profile page; associate a word document or pdf with their post)
Group(a user can create any number of groups other users can join)
What is the proper approach to break this apart, I was thinking that each was an AR in this scenario?
It seems as if there is a FK repationship between User and the other AR in this scenario, should this association be represented in a Value object or AR?
Since the file AR seems to be connected to both User and Post in a FK type relationship, how should I represent this from AR's or Value objects?
One to many
User -> Posts
User -> File
User -> Group
One to many
Posts -> File
If a root aggregate holds a reference to another root aggregate the boundary of the former is violated and the whole concept of an aggregate is corrupted, so I believe if a root aggregate looks like needing to hold a reference to another root aggregate, then I need to create a different entity, that will probably share some of the same members a...
Aggregates accept business commands, which usually results in producing an event related to the business domain – the Domain Event. If you'd like to learn more about DDD and aggregates, it's best to start with Eric Evans' original book. There's also a great series about effective aggregate design written by Vaughn Vernon. Definitely worth reading.
Each aggregate has a root and boundary. The root is a single specific entity contained in the aggregate. This object as the only one in the aggregate can have references to classes outside the aggregate limits. Local entities within the aggregate may have references to each other.
Your aggregate root object should (generally) only have properties which are part of its domain. If you have an AR object with a property which is not in the aggregate then you are immediately faced with the question. 'Why not?'
When designing aggregate roots you must ask yourself, what is this entity defined by rather than what does this entity "have". For example, can a user exist without a post? I'm guessing yes. So a Post would be its own AR in this scenario. All you need is to reference the UserID in this case.
Most of your entities will end up being AR's. Remember that you are modeling a solution to a business problem here, and not database tables. This messed me up a lot when I started DDD. You have to ask yourself tough questions, like why does my User entity need a collection of Posts? You may have just one business rule that says you can only have 10 posts in the first month (just an example). For that you could instead just have an int field called TotalPosts and lose the collection all together. Now you don't have to load potentially hundreds of Post objects just to load a User.
So in summary, you want mostly AR's in your domain that reference each other by ID only. Your domain probably won't match your DB schema. It's OK to have multiple "versions" of the same AR for different bounded contexts in your domain.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With