Search code examples
repositorydomain-driven-designdto

In DDD, how do you work with multiple repositories for read-only lists


What do you do if you need to generate a read-only list of data on a page and that data would naturally come from several, potentially 5 or more different repositories?

We're using DDD and have been forcing access to our database through repositories, but there is a scenario that has come up that doesn't seem to fit DDD and we're trying to decide on the best pattern to use.

For example, let's say that you have a community based web site with videos, forums, blogs, etc. You've got a forums page with a list of comments. This is rough, but I hope it makes sense.

<table>
<tr><td>User Name (with possible link)</td><td>User's community score.</td><td>User Avatar</td><td>User's E-mail</td><td>User's blog</td><td>User's videos</td></tr>
</table>
<table>
<tr><td>This is a comment.</td></tr>
</table>

So each comment contains several different pieces: a user Name, a community score, an avatar, an e-mail, a user's blog and a user's video page. Traditionally, these pieces of information would all come from separate repositories.

The issue with that is efficiency. Repositories can be maximized, but only around the aggregate for which their created. Using repositories becomes inefficient for read access the moment that you need access to data that lies in more than one repository.

My solution is to create a UserInformation DTO with the relevant information and place a method in the UserForumsRepository with the signature

ILIst<UserInformation> GetUserForumsUserInformationByForumPostID(int forumPostID).

One of my colleagues suggests that using a DTO in this way breaks the design pattern that we've been using and suggests that a better way would be to get a list of forum comment ids and then pass those ids into the various repositories to return the results.

My own view is that main purpose of repositories is to encapsulate business logic which is important for the CUD parts of CRUD, but that read-only lists should be generated in the way that makes most sense. If appropriate, I think that it even makes sense to remove the read-only list methods from the repository entirely (e.g. such as in a common widget that's used across multiple different types pages).

How do you handle this situation?


Solution

  • Answer #2

    What's needed here is an extra service layer between the concrete repository and the client. Sometimes, what the client needs is different from what the repository layer provides, especially in the case where the repositories may be distributed. A service layer allows you to define coarsely grained methods and hide the finely grained details from the client. With a services layer, you're then passing lightweight DTOs on to the client, instead of full fledged business objects.

    To map the business objects to DTOs and the reverse, the tool Automapper is becoming quite popular.