DDD: Aggregate Root accessed by another aggregate root
Asked Answered
D

1

7

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
Devisal answered 7/11, 2014 at 21:32 Comment(1)
Could you add a diagram or something to clear things up? As it stands, there could be several different ways to solve this.Papandreou
L
6

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.

List answered 9/11, 2014 at 18:44 Comment(6)
One thing that is confusing is the file scenario. The file AR seems to be connected to a user through the profile picture and connected to the posts through a user being able to upload word and pdf documents to associate with a post. With that in mind, where should I add the file from? Should I add profile pic from the user service and add the documents from the profile service? It seems like a violation if I have the user and profile call the file service, how should I handle this interaction?Devisal
I would have File be its own AR. Next I would have a method on my User AR, called AssignProfilePic(int fileID). Then on the Post AR I would have a method called AttachFile(int fileID).List
When you say the User AR, do you mean the User service or the User AR entity object for adding the AssignProfilePic? With the AR's located in their own Bounded Context, would the AssignProfilePic method access the File Repository in the File Bounded Context?Devisal
I meant on the User AR directly. Put behavior directly on your entities whenever possible, domain services should be your second choice reserved for situations where multiple entities need to be orchestrated. So in your situation, I would first create the File AR and persist it to a File repository. I would then take the newly created File AR and assign it to my user: user.AssignProfilePic(file.ID). Finally save the user to the user repository. You can orchestrate this in either an application service or domain service.List
Gotcha. One more thing, what does that mean for the association between File and Post, since a post can have multiple Files of type pdf or word document?Devisal
On the Post AR you can maintain a list of FileID's currently attached to the Post. To attach a file, simply create a method called AttachFile(int fileID) and then check to make sure file id doesn't exist already, then add the id to the list.List

© 2022 - 2024 — McMap. All rights reserved.