2

I decided to get acquainted with a concrete CQRS implementation on the example of Greg Young's implementation

What I do not understand is what is the meaning of services here because it seems to be completely other than we used to in common three-tier pattern.

The client changes the received DTO and it creates a command which is handled by its handler which calls a method of a domain object.

Then the event is created and stored in the event store and published to syncronise the denormolized part.

I cannot find the service in this chain.

My co-worker told me that for example that if we do not want to store large data as part of a domain when we store in reports but when we need it in our domain we publish an event which returns something from the service.

But I cannot clearly form the picture in my mind.

Can anyone explain what services are supposed to do here?

user247702
  • 23,641
  • 15
  • 110
  • 157
Yurii Hohan
  • 4,021
  • 4
  • 40
  • 54

4 Answers4

6

In CQRS, basically the command handlers are what you'd call application services in non-CQRS scenarios.

Dennis Traub
  • 50,557
  • 7
  • 93
  • 108
  • It is debatable because as I looked through the implementation I had a feeling that the service layer responsibilities are split between command handlers and domain level – Yurii Hohan Sep 20 '11 at 18:02
  • Well, at least that's how I understand Greg. He was talking about this very topic just yesterday on a course I'm attending. But I'm sure there are exceptions. – Dennis Traub Sep 21 '11 at 07:13
1

'Services' can represent different things depending on the context you are talking about. Reading the article I believe he is using the term 'service' in the context of Domain Services which form the building blocks of DDD.

However, in CQRS you typically have a command service and query service, which in DDD context represent the Application Service Layer. But as I say, reading the article, I think his use of the word 'service' is meant for domain services.

David Masters
  • 8,069
  • 2
  • 44
  • 75
  • Well, I do not think so. The services in DDD are meant to contain business logic. A quote by Fowler:"A Service Layer defines an application's boundary [Cockburn PloP] and its set of available operations from the perspective of interfacing client layers. It encapsulates the application's business logic, controlling transactions and coor-dinating responses in the implementation of its operations.". First - this action is done by command handlers and domain here and second is that the arrows show that this application of term Service is not appliable. But I might be wrong – Yurii Hohan Sep 20 '11 at 18:11
  • You are confused with the 'Application Service Layer' and 'Domain Services'. These are two different things. – David Masters Sep 21 '11 at 08:04
0

When you have problems like Set Consistency Validation. For example: Set Validation Post in SO you may need a Service that ensures that incoming duplicate commands of a value that should only be persisted once are rejected. In this case, a service basically does an insert in a Sql table with a primary key constraint. It only happens once, otherwise, throws an error and the whole process fails and no events are generated, no reporting in the query side. Just a case.

Community
  • 1
  • 1
Narvalex
  • 1,824
  • 2
  • 18
  • 27
0

You mean about service a remote facade (Web service) which will call application layer, because domain service is a different thing.

The remote facade layer (web service) if you are designing n-tier application to expose application services to other tiers will expose your business and commands by calling the application layer, the application layer as mentioned by David:

For Read Part, in your application layer you need to design a Query Service with methods like FindOrders(x, y, z), GetMostOrderedItems(), ...

For the Write part, you can design the command service in one of many ways like:

  • Service which takes DTOs and execute domain logic based on it [Least CQRS]:
public void ActivateOrder(int orderID)
{
    var order = _orderRepository.FindOrder(orderID);
    order.Activate();
}

public void UpdateClientAddress(ClientAddressDTO address)
{
    var client = _clientRepository.FindClient(address.ClientID);
    client.Address = // .. map ClientAddressDTO to Address
}
  • Service which takes DTOs and convert it to a Command to be executed on domain model:
public void ActivateOrder(int orderID)
{
    var orderActivationCommand = new OrderActivationCommand(orderID);
    _commandExecuter.Execute(orderActivationCommand);
}

public void UpdateClientAddress(ClientAddressDTO address)
{
    var clientMovingCommand = new clientMovingCommand(address.ClientID, address.PostalCode, ...);
    _commandExecuter.Execute(clientMovingCommand);
}
  • Generic Service which takes a Command object (instead of DTO) and execute it:
// ... in remote facade or client code ...

var orderActivationCommand = new OrderActivationCommand(orderID);
_commandService.ExecuteCommand(orderActivationCommand);

// ... in application layer (service) ...

public void ExecuteCommand(Command command)
{
    _commandExeuter.Execute(command);
}
Marcos Dimitrio
  • 6,651
  • 5
  • 38
  • 62
Mohamed Abed
  • 5,025
  • 22
  • 31
  • I meant services in the way they are mentioned in the diagram. You posted some snippets I have already seen in Greg's implementation but they do not help me to see the logic – Yurii Hohan Sep 20 '11 at 18:07
  • The service in the diagram is domain service not application service, which is a domain logic not related to one aggregate root .. like bank transfer, it is domain logic related to two aggregate roots (entities) so it should be implemented in a BankTransferService.Transfer(a1, a2, 500); even with commands and command handlers sometimes you cant find a single aggregate root or entity to apply the domain logic so you have to depend upon a domain service – Mohamed Abed Sep 20 '11 at 18:30
  • Check: http://stochastyk.blogspot.com/2008/05/domain-services-in-domain-driven-design.html http://lostechies.com/jimmybogard/2008/08/21/services-in-domain-driven-design/ – Mohamed Abed Sep 20 '11 at 18:32
  • How does it update the denormalized DB then if it has no direct link to it? Does this service publish the event? – Yurii Hohan Sep 20 '11 at 18:34
  • It does not update the denormalized DB it is just called from event publisher or thin data layer in order to calculate or process some domain logic and return the result as dto for querying purposes. re-check the diagram – Mohamed Abed Sep 20 '11 at 20:55
  • Let us suppose you transfered your money with your BankTransferService.Transfer(a1, a2, 500) method. What is happening then? Shall the service raise the event to change the denormalized view? Because as we see it has to be changed in some way. And one more question - Why do not we do it with the help of MoneyTransfered command? – Yurii Hohan Sep 21 '11 at 07:17
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/3650/discussion-between-hohhi-and-mohamed-abed) – Yurii Hohan Sep 21 '11 at 07:18