Application Services
This is a handler where commands are received and delivered to the addressed Aggregate. We call these handlers ApplicationService. This is the write side in CQRS.
Communication Guide Table
Triggered by | Description |
---|---|
Command | A command is used to dispatch domain model changes. It can either be accepted or rejected depending on the domain model invariants |
Best Practices
{% hint style="success" %} You can/should/must...
- an appservice can load an aggregate root from the event store
- an appservice can save new aggregate root events to the event store
- an appservice can establish calls to the ReadModel (not common practice but sometimes needed)
- an appservice can establish calls to external services
- you can do dependency orchestration
- an appservice must be stateless
- an appservice must update only one aggregate root. Yes, this means that you can create one aggregate and update another one but think twice {% endhint %}
{% hint style="warning" %} You should not...
- an appservice should not update more than one aggregate root in single command/handler
- you should not place domain logic inside an application service
- you should not use application service to send emails, push notifications etc. Use Port or Gateway instead
- an appservice should not update the ReadModel {% endhint %}
Examples
public class AccountAppService : AggregateRootApplicationService<Account>,
ICommandHandler<RegisterAccount>,
ICommandHandler<ActivateAccount>,
ICommandHandler<SuspendAccount>,
ICommandHandler<ResetAccountPassword>,
ICommandHandler<ChangeAccountEmail>,
ICommandHandler<ChangeAccountUsername>
{
public void Handle(SuspendAccount message)
{
Update(message.Id, account => account.Suspend());
}
...
}