The repository in the CommonDomain only exposes the "GetById()". So what to do if my Handler needs a list of Customers for example?
4 Answers
On face value of your question, if you needed to perform operations on multiple aggregates, you would just provide the ID's of each aggregate in your command (which the client would obtain from the query side), then you get each aggregate from the repository.
However, looking at one of your comments in response to another answer I see what you are actually referring to is set based validation.
This very question has raised quite a lot debate about how to do this, and Greg Young has written an blog post on it.
The classic question is 'how do I check that the username hasn't already been used when processing my 'CreateUserCommand'. I believe the suggested approach is to assume that the client has already done this check by asking the query side before issuing the command. When the user aggregate is created the UserCreatedEvent will be raised and handled by the query side. Here, the insert query will fail (either because of a check or unique constraint in the DB), and a compensating command would be issued, which would delete the newly created aggregate and perhaps email the user telling them the username is already taken.
The main point is, you assume that the client has done the check. I know this is approach is difficult to grasp at first - but it's the nature of eventual consistency.
Also you might want to read this other question which is similar, and contains some wise words from Udi Dahan.

- 1
- 1

- 8,069
- 2
- 44
- 75
-
Nice answer and you are right: This IS difficult to grasp. Especially the thing about doing client side compensation which just doesn't _feel_ right :). Consider the example from the link you provided where a new user must be unique. Doing client side compensation will only be valid in a CQRS-ES (no write database). If it were a system with no ES but perhaps instead a master write database the Command would probably fail due to some database constraint. At times it seems that compensation as a golden rule is overkill. Keep it simple :) – Werner Aug 30 '11 at 07:20
-
Also as a side note. Udi Dahan says in his Clarified-CQRS (http://www.udidahan.com/2009/12/09/clarified-cqrs/) that "The server would still validate all commands that arrive, not trusting clients to do the validation". But perhaps that only applies for CQRS where you have a write master? – Werner Aug 30 '11 at 09:16
In the classic event sourcing model, queries like get all customers would be carried out by a separate query handler which listens to all events in the domain and builds a query model to satisfy the relevant questions.
If you need to query customers by last name, for instance, you could listen to all customer created and customer name change events and just update one table of last-name to customer-id pairs. You could hold other information relevant to the UI that is showing the data, or you could simply hold IDs and go to the repository for the relevant customers in order to work further with them.

- 6,310
- 2
- 33
- 57
-
The list of customers are not relevant to the UI. Imagine it is about validating a "CreateCustomer" command. Part of that validation involves getting some data from all other customers. This is not UI - this is a command Handler. Does it query a read database to get this list? – Werner Aug 23 '11 at 07:40
-
Yes indeed, it could. That is how it could handle set-based validation as mentioned above. Your read model for that might just be an in-memory or memcached-like hashtable of existing usernames. How consistent that read model is with the rest of your read models is up to you. – Sebastian Good Sep 14 '11 at 23:03
You don't need list of customers in your handler. Each aggregate MUST be processed in its own transaction. If you want to show this list to user - just build appropriate view.

- 2,220
- 1
- 19
- 24
-
But I _am_ only processing 1 aggregate. Example: Handling of "CreateCustomer" will depend on information about all customers. For example I need to register that this is the 5'th "Donald Duck" created. Do I go to a query side for the list of Customers that are named "Donald Duck"? – Werner Aug 22 '11 at 14:29
-
In this case you need another aggregate which will track objects creation. Customer and Tracking aggregate should communicate through events and saga. – xelibrion Aug 22 '11 at 16:24
-
Your command needs to contain the id of the aggregate root it should operate on. This id will be looked up by the client sending the command using a view in your readmodel. This view will be populated with data from the events that your AR emits.

- 5,263
- 20
- 24
-
But let's assume that I for some funny reason needed a list of customers to query. I can't come up with an example that makes sense, but suppose my "CustomerCreated" handler needed information about how many other customers are called "Donald". Is this information required as input in the command request (i.e. delivered by the callee in CreateCustomer) or is it alright to query a Customer-read-side from within my handler? – Werner Aug 22 '11 at 14:24
-
1@Werner, out of interest why did you except this as the answer? This doesn't really answer the question about the command handler needing to obtain a list of customers. – Chris Moutray Aug 24 '11 at 12:24
-