The Domain layer is the core of the application.


Here is the right place for complex business logic e.g. calculation, validation, transaction handling, file creation etc. Business logic is a step-up on complexity over CRUD (Create, Read, Update and Delete) operations. A service can be called directly from the action handler, a service, the console and from a test.

Domain vs. Infrastructure

The infrastructure (layer) does not belong to the core application because it acts like an external consumer to talk to your system, for example the database, sending emails etc.

An Infrastructure service can be:

  • Implementations for boundary objects, e.g. the repository classes (communication with the database)
  • Web controllers (actions), console, etc.
  • Framework-specific code

By separating domain from infrastructure code you automatically increase testability because you can replace the implementation by changing the adapter without affecting the interface users.

Within the Domain layer you have multiple other types of classes, for example:

  • Services with the business logic, aka. Use cases
  • Value Objects, DTOs, Entities, aka. Model
  • The repository (interfaces), for boundary objects to the infrastructure.

Keep it clean

Most people may think that this pattern is not suitable because it results in too many files. That this will result in more files is true, however these files are very small and focus on exactly one specific task. You get very specific classes with only one clearly defined responsibility (see SRP of SOLID). So you should not worry too much about too many files, instead you should worry about too few and big files (fat controllers) with too many responsibilities.

Read more

This architecture was inspired by the following resources and books: