Skip to main content

Domain Layering

In order to fulfil Domain Driven Design's (DDD) requirement for a pure domain layer, we can use the Layered Architecture pattern to provide isolation for the domain logic from the rest of the service. Expanding outwards, we can then provide isolation for the controllers of the flow of the business process (called the application layer), and finally isolation for the necessary infrastructure to support the service (called the infrastructure layer). These three layers provide us with a structured framework on which all DDD-driven services are built.

Domain Driven Design Layered Architecture

The Domain Layer

The domain layer is a pure implementation of business actions, arranged by Aggregates - the data models of your business. Aggregates are responsible for all business logic, and raise Domain Events when their state changes.

Domain Events, raised by the Aggregates, are used to notify other services of the changed state of the Aggregate. Domain Events are also used to notify the Application Layer of the changed state of the Aggregate.

The domain layer is the innermost layer of DDD's layered architecture, and as such is a pure layer, so does not rely or have dependency on any other layer, service or component to perform it's functions.

A domain layer will consist of:

  • Domain Models, called Aggregates, containing all business logic
  • Domain Events containing the changed-state data that is raised by the Aggregates
  • Exceptions, raised by the Aggregate, when business logic fails

Domain aggregate actions are:

  • Dependency Free - No Domain component may use any non-Domain Layer component
  • Self Validating - Actions must validate inputs before any processing
  • State Changing - The action must result in a change of the Domain's state
  • Event Recording - All actions must record a Domain Event describing the state change

The Application Layer

The application layer coordinates service process. The application layer only handles reading instructions and deferring to the domain aggregates, and can be thought of as a "process manager" for the service that accepts an instruction (a command), may read or lookup data, and then calls the domain layer to perform the action. The application layer may also read data (a query) from the domain layer, and return it to the caller.

The "command" and "query" behaviour of the application layer is implemented using the Command Query Responsibility Segregation (CQRS) pattern.

Therefore, an Application Layer will only consist of:

  • CQRS Commands to perform domain actions.
  • CQRS Queries to return domain state.
  • Define Policies that act on domain events within the service.

The Infrastructure Layer

The Infrastructure layer contains components that are required only by the service, encompassing anything that is not part of the business process.

Anything that is not part of the Domain or Application layer is the Infrastructure layer. This layer contains non-business process code such as:

  • Controllers listening to HTTP calls
  • Domain Event handlers listening to the global message queue
  • Data Layer (including persistence domain aggregates and implementations of domain repository interfaces)

Infrastructure components can also be any functionality-adding library that you would install via a package manager.

Further Reading