1

Having read this question and it's answers as well as some other resources, I think my application has 3 aggregate roots, and as such should have 3 matching repositories but I'm unsure how the repositories should be used when I need to fetch data which is one of the other aggregate roots.

Le's look at an example. Imagine a more simple version of Stack Overflow which has the notions of Users, Tags and Questions. In my mind, these are all aggregates roots, because we need to list and query against them, and as such should each have it's own repository.

Given the situation where you view a user profile and you also want to display all of the questions that the user has posted, should you use the QuestionsRepository from within the UsersRepository to populate a user.Questions array?

I believe this question is more a matter of separation of concerns but it addresses the point of how repositories should interact. As I see it, it becomes very easy to produce circular references between repositories.

E.g. The UsersRepository fetches all the users questions from the QuestionsRepositiory which for each question fetches the user data using an instance of UsersRepository and so on.

Now let's take the converse (which I just touched on a little). To list all the questions we would use the QuestionsRepository and call a GetAll() method (or similar). In this listing, we want to display the user information so we need to fetch it from the database.

Ideally in this situation, we'd want to perform a join from Questions to Users rather than getting all the questions and iterating over them fetching the user each time, giving us an N+1 situation and a load of unnecessary trips to the database.

Is the QuestionsRespository allowed to instantiate Users to perform the join? or does it have to use the UsersRepository, preventing a single trip to the database.

The obvious follow-on from this is where you're given a Tag and need to display all the Questions and their Users. Should the TagsRepository use the QuestionsRespository to fetch all questions where tag LIKE 'tag-name' which in turn uses the UsersRepository to get the user info for each question? or is TagsRepository allowed to instantiate Questions and Users to populate the object graph?

Community
  • 1
  • 1
Greg B
  • 14,597
  • 18
  • 87
  • 141

1 Answers1

2

Try to consider using Repositories as such only for changing data (commands) and having separate service / "read repository" for query operations that are read-only - and bypasses the usual repositories, going straight to database, reading the data using sql queries optimized for a particular case. I would still use the usual Repositories when you need information that you can easily get using a Repository (i.e. displaying detail about one User), but use a read-only service for more complicated scenarios (i.e. screen that shows some summary that combines data from more Aggregate Roots in rather complex way). However make sure to ALWAYS use Repositories for changing data.

You can go even further in this and look into a pattern called CQRS - Command Query Responsibility Segregation (www.cqrsinfo.com) which is basically about completely separating the parts of application that changes application state from the parts of application that read / query application state), although it takes some time to get a grasp on it. (Note that CQRS is something different than CQS).

Greg B
  • 14,597
  • 18
  • 87
  • 141
Tomas
  • 553
  • 4
  • 9