- Basic Request Flow Through Domain-Driven Architectural Layers
- More-detailed Request Flow Through Domain-Driven Architectural Layers
- Solution Structure
Domain
- References only generic base-class libraries
- Contains entities and value objects in the root, with sub-folders for concepts like Commands, Events, and Domain Services.
Services
- Domain Services: stateless containers of domain-level interaction between domain objects.
Commands
- A abstraction of a request for a change in state. Usually involves one or more events being published.
Events
- A abstraction of a record of a past state change.
Builders
- Used to build instances of domain objects (Aggregates, Entities, Commands, Events, etc.), enforcing and validating (via validators) invariants. Like factories, but present a domain-specific fluent interface that .
Validators
- Encapsulates some of the critical business logic relating to invariants relating to instantiating domain objects.
Exceptions
- Domain-specific exceptions (e.g.
EntityNotFoundException
,EntityAlreadyExistsException
, etc.)
- Domain-specific exceptions (e.g.
Abstractions
- interfaces, repositories, etc.
Application
- References Domain
Services
- Application services; responsible for task coordination of use case flows, one service method per flow. [Vernon, Implementing Domain-Driven Design p. 521]
Commands
- Application commands that cross aggregate boundaries; referencing domain objects
Events
- Application events that cross aggregate boundaries; referencing domain objects
Translators
- Used within adapters to translate the data from one interface to another, leveraging builders and validators from the Domain
Builders
- Used to build instances of application objects, making use of validators to enforce application-level invariants.
Validators
- Used when translating between domain events/commands and application events/commands
Exceptions
- Domain exceptions that are not specific to an particular aggregate.
Abstractions
Infrastructure
- References Domain and Application, and frameworks
- The infrastructure-level implementation details of the Application and Domain Layers.
Services
- Infrastructure Services
Abstractions
- Interfaces and base classes relating to infrastructure
Persistence
- Infrastructure Services and generic base classes implementing data persistence.
Dtos
- Objects representing the shape of data required to communicate to external services.
Translators
- Translates DTOs to domain-objects (and vice-versa), making use of Builders and Validators to enforce invariants relating to instantiation of domain objects.
Builders
- Encapsulates the rules for instantiating domain objects, making use of Validators
Validators
- Validation code that enforces invariants relating to infrastructure DTOs. May mirror Domain-level invariants.
Exceptions
- Infrastructure-specific exceptions.
- Implementations?
- Persistence? (repository implementations, specifications, etc.)
WebAPI
- References both Domain and Infrastructure(?).
Dtos
?Validators
- Validation code that enforces invariants relating to WebAPI DTOs. May mirror Domain-Level invariants.
ApplicationCommandDtos
?Translators
Validators
ApplicationEventDtos
?Translators
Validators
Controllers
- Obvious
Infrastructure
- TODO:
Endpoint
- References both Domain and Infrastructure?
- todo:
Tests
The Application Layer contain use cases (that are collaborations of application services and domain objects). Concepts in the Application Layer are Domain focused. For example, in a domain there may be an abstract concept like notification: something in the domain may need to notify something else in the domain. Kow that notification is realized needs to be implemented in the real world. So, within the scope of the application there may be a Notification Service. The implementation (i.e. the infrastructure behind the notification service) may be to send an email, so it ends up being a wrapper to an Infrastructure Service (Email Sender).
DTO are anemic data containers. Validation, serialization, etc. requirements use asp.net specific attributes.
Is this just application services? Be clear about the distinction of application services.
Core shouldn't know about front-ends, so translation to/from domain happens in front-end.
Domain classes have all read-only properties, mutation is done through methods (ala Command Query Separation.)
Test names detail the expectation, no need for assert text.
Tests verify controllers via test server.