Example: Your database has a SQL view named "CustomerOrdersOnHold". This view returns a filtered mix of specific customer and order data fields. You need to fetch data from this view in your application. How does access to such a view fit into the repository pattern? Would you create a "CustomerOrdersOnHoldRepository"? Is a read-only view such as this considered an aggregate root?
3 Answers
I would prefer separating the read repository, preferably even change its name to Finder or Reader, the repository is meant for Domain usage not for querying read-only data, you can refer to this article and this which explains the usage of Finder separated form repository.
I would recommend also the separating of read model from write model architecture CQRS and there
This architecture allows you to separate the read model from write model even in terms of data storage and the use of event sourcing.
For a middle solution you can utilize some CQRS concepts without the complexity of separating database by just separating repository from finders, read this post
for a sample of this type of solution (use the same database but separating finders form repositories) check this sample

- 1,274
- 10
- 24

- 5,025
- 22
- 31
-
I think this is the best answer. This type of data/objects are nothing to do with the domain, and as Mohamed has pointed out, the term repository is associated with aggregates/domain/transactions, so the use of this term could be misleading. CQRS is aimed at solving this exact issue. I asked a similar question a while back: http://stackoverflow.com/questions/2098112/ddd-how-to-implement-performant-repositories-for-searching – David Masters Sep 12 '11 at 12:44
-
Great answer due to the great links. This helped me view my code from a different and clearer perspective. – Landon Poch Sep 30 '12 at 21:56
-
If you have a Finder, how do you name the "Saver"? Repository? But then a repository should be able to access the data AKA "query"... how to address this? – JorgeeFG Mar 10 '17 at 16:01
-
Name is Repository. The repository does not query (as in search) it only gets object by Id. Where Finder will do all fancy querying. Also if you do follow CQRS and have different read model, the Finder will return a different object anyway where the Repository will return the domain object. – Mohamed Abed May 15 '17 at 00:09
-
@MohamedAbed you "this article" and "this" links are dead. – Saber Jul 06 '17 at 13:01
I think that it is fine to have a separate repository like "CustomerOrdersOnHoldRepository". The interface of the repository will reflect the fact that the objects are readonly (by not defining Save/Add/MakePersistent method).
From How to write a repository:
... But there is another strategy that I quite like: multiple Repositories. In our ordering example there is no reason we can have two Repositories: AllOrders and SurchargedOrders. AllOrders represent a list containing every single order in the system, SurchargedOrders represents a subset of it.
I would not call returned object an Aggrgate Root. Aggregates are for consistency, data exchange and life cycles. Your objects don't have any of these. It seems that they also can not be classified as Value Objects ('characteristic or attribute'). They are just standalone classes.

- 17,078
- 2
- 44
- 70
-
I was leaning toward giving the view its own repository, however, it is my understanding that repositories operate upon aggregate roots only (http://thinkddd.com/glossary/aggregate-root/). – 300 baud Sep 09 '11 at 19:16
-
This rule is about avoiding direct access to internal parts of aggregate. You don't have these internal parts, just like you don't have any invariants and lifecycle. It is ok to return these objects from repository. Call them Aggregate Roots if you like but that can be a bit misleading. – Dmitry Sep 09 '11 at 19:29
Your read-only data would be considered Value Objects in the DDD world.
I typically place access methods for value objects in existing repositories until such time that it makes sense to create a separate repository. It's similar to a method that might return a static list of states to be used on an address form:
IAddressRepository
{
Address GetAddress(string addressID);
List<string> GetStates(string country);
}

- 17,084
- 11
- 59
- 78
-
So in your scenario, if I have a CustomerRepository or an OrderRepository I would add a method to one of these repositories? i.e. `ICustomerRepository.GetCustomerOrdersOnHold(args)` or `IOrderRepository.GetCustomerOrdersOnHold(args)`? – 300 baud Sep 09 '11 at 20:30