Reputation: 19717
I'm having problems finding a possible aggregate root and identifying the proper repositories within my application.
The scenario is like this: I'm writing a library application to practice DDD. The application allows the user to display all books, create a new book or edit an existing one. A book has exactly one author and one publisher assigned. In the application the user can also display, create and edit authors/publishers independently.
At the moment I am using three different repositories - BookRepository, AuthorRepository and PublisherRepository - in order to load a book, the associated author and the publisher. All three repositories are used within my ApplicationService to create a new book.
Looking at this code, it looks to me like I am missing an aggregate root. I thought that maybe the Book class could be an aggregate root. This would mean that the BookRepository would load all the data combined (book, author, publisher), which sounds just fine. This works great when loading a single book, but what happens if I need to display all authors and allow the user to create, edit or delete an author? I could not do that with the Book class as an aggregate root.
How can an aggregate root and its associated repositories be identified?
If the BookRepository is indeed the aggregate root...
...how would the methods for subordinate entities i.e. for the authors and publishers look like (for example repository.GetBookAuthor, repository.UpdateBookAuthor)?
...how do I manage the authors / publishers (for example to display all the authors for editing)?
Upvotes: 1
Views: 397
Reputation: 1718
When modeling an aggregate root, you must ask yourself "What is this entity defined by?", rather than "What is this entity associated with?" The natural tendency is to look at entities like a database table, then try to find the foreign keys. With DDD you are modeling business invariants, so your entity models need to reflect the invariants you are trying to enforce and nothing more. The reason you use repositories with DDD is that your entity model probably will look different than your data model. If all you are doing is CRUD though, your models will probably look the same. In which case, you might want to reevaluate if you will even benefit from DDD.
In your case I would model books, authors, and publishers, all as their own aggregate. They would only be associated by ID. So the book object, would only have a property called AuthorID. The publisher wouldn't have a list of book objects, instead just put a publisherID on the book object. The reason is that the publisher is not defined by the books they publish, since it's possible for them to have no books at all.
Since you are mainly making a CRUD app as a learning experience, it might be hard to really explore the benefits of DDD. I suggest you invent some business invariants to try and model for practice.
Also I recommend you read up on CQRS, if you are wondering how your query needs would be met if your aggregates don't have all the properties to satisfy some queries.
Upvotes: 4