Domain Driven Design: Domain Service, Application Service

Viewed 114560

Can someone explain the difference between domain and application services by providing some examples? And, if a service is a domain service, would I put the actual implementation of this service within the domain assembly and if so, would I also inject repositories into that domain service? Some info would be really helpful.

8 Answers

Services come in 3 flavours: Domain Services, Application Services, and Infrastructure Services.

  • Domain Services : Encapsulates business logic that doesn't naturally fit within a domain object, and are NOT typical CRUD operations – those would belong to a Repository.
  • Application Services : Used by external consumers to talk to your system (think Web Services). If consumers need access to CRUD operations, they would be exposed here.
  • Infrastructure Services : Used to abstract technical concerns (e.g. MSMQ, email provider, etc).

Keeping Domain Services along with your Domain Objects is sensible – they are all focused on domain logic. And yes, you can inject Repositories into your Services.

Application Services will typically use both Domain Services and Repositories to deal with external requests.

Hope that helps!

Think a Domain Service as an object that implements business logic or business rules related logic on domain objects and this logic is difficult to fit into the same domain objects and also doesn't cause state change of the domain service (domain service is an object without a "state" or better without a state that has a business meaning) but eventually change the state only of the domain objects on which operates.

While an Application Service implements applicative level logic as user interaction, input validation, logic not related to business but to other concerns: authentication, security, emailing, and so on.., limiting itself to simply use services exposed by domain objects.

An example of this could be the following scenario thinked only for explaining purpose: we have to implement a very little domotic utility app that executes a simple operation, that is "turn on the lights, when someone opens the door of an house's room to enter in and turn off the light when closes the door exiting from the room".

Simplifying a lot we consider only 2 domain entities, which are not part of the same aggregate: Door and Lamp, each of them has 2 states, respectevely open/closed and on/off, and specific methods to operate state changes on them. The entities need to be part of different aggregates so that the following logic can't be implemented in the aggregate root.

In this case we need a domain service that executes the specific operation of turn on the light when someone opens the door from the outer to enter into a room, because the door and the lamp objects cannot implement this logic in a way that we consider suited to their business nature. This new domain service needs to encapsulate some business process that should always happen, triggered by some domain event/method.

We can call our domain service as DomoticDomainService and implement 2 methods: OpenTheDoorAndTurnOnTheLight and CloseTheDoorAndTurnOffTheLight, these 2 methods respectevely change the state of both objects Door and Lamp to open/on and closed/off.

The state of enter or exit from a room it isn't present in the domain service object and either in the domain objects, but will be implemented as simple user interaction by an application service, that we may call HouseService, that implements some event handlers as onOpenRoom1DoorToEnter and onCloseRoom1DoorToExit, and so on for each room (this is only an example for explaining purpose..), that will respectively concern about call domain service methods to execute the attended behaviour (we haven't considered the entity Room because it is only an example).

This example, far to be a well designed real world application, has the only purpose (as more times said) to explain what a Domain Service is and its difference from an Application Service, hope it is clear and useful.

Also, the example domain service above could easily be replaced by domain events which are used to explicitly implement side effects across one or multiple aggregates, but since these are not the subject of this question, I only mention them here so the reader can be aware of their existence and later decide which approach is better for them.

Domain Services: A service that expresses a business logic that is not part of any Aggregate Root.

  • You have 2 Aggregate:

    • Product which contains name and price.
    • Purchase which contains purchase date, list of products ordered with quantity and product price at that time, and payment method.
  • Checkout is not part of either of these two models and is concept in your business.

  • Checkout can be created as a Domain Service which fetches all product and compute the total price, pay the total by calling another Domain Service PaymentService with an implementation part of Infrastructure, and convert it into Purchase.

Application Services: A service that "orchestrates" or exercises Domain methods. This can be as simple as just your Controller.

This is the place where you usually do:

public String createProduct(...some attributes) {
  if (productRepo.getByName(name) != null) {
    throw new Exception();
  }

  productId = productRepository.nextIdentity();

  product = new Product(productId, ...some attributes);

  productRepository.save(product);

  return productId.value();
  // or Product itself
  // or just void if you dont care about result
}

public void renameProduct(productId, newName) {
  product = productRepo.getById(productId);

  product.rename(newName);

  productRepo.save(product);
}

You can do validations here like checking if a Product is unique. Unless a Product being unique is an invariant then that should be part of Domain Service that might be called UniqueProductChecker because it can't be part of Product class and it interacts with multiple Aggregates.

Here is full-blown example of DDD project: https://github.com/VaughnVernon/IDDD_Samples

You can find lots of examples of Application Service and a couple of Domain Service

Related