This project is part of the MessageHandler processing patterns library.
MessageHandler is distributed under a commercial license, for more information on the terms and conditions refer to our license page.
An aggregate is a cluster of domain objects that is treated as a single unit. Any references from outside the aggregate should only go to the aggregate root. The root can thus ensure the integrity of the aggregate as a whole.
As an aggregate root is responsible for maintaining integrity of the whole, it is the primary responsible for deciding if a command can be executed on the aggregate or not.
This decission will be recorded as an event on an event stream and any internal state is updated in response to the recorded event.
Use this pattern every time a user, or an automated part of the system, wants to make a change.
Encapsulate the intent into a command and send it to the aggregate root, so that it can take a decission on how to respond to the intent.
The scenario for this quickstart is e-commerce process, where you can place a booking through an API, and the aggregate root will decide if it is a valid purchase order or not.
- The .NET 6 SDK should be installed
- The sample was created using Visual Studio 2022 community edition
- A general purpose azure storage account is used to store events.
- To use the outbox an azure service bus namespace or eventhub is required.
- The MessageHandler.EventSourcing.AzureTableStorage package is available from nuget.org
- The optional MessageHandler.EventSourcing.Outbox package is also available from nuget.org
Prior to being able to run the sample, you need to configure the user secrets file.
In the secrets file you must specify the following configuration values.
{
"azurestoragedata": "your azure storage connection string goes here",
"servicebusnamespace": "your azure service bus connection string goes here"
}
Also ensure a topic named orderbooking.events
is created up front in the service bus namespace.
Once configured you can start the API project or run the unittests.
MessageHandler is intented to be test friendly.
This sample contains plenty of ideas on how to test an aggregate root without requiring a dependency on an actual storage account or servicebus namespace, and thus keep the tests fast.
- Unit tests: To test the actual logic in the aggregate root. Unit tests should make up the bulk of all tests in the system.
- Component tests: To test the api used to expose the aggregate root.
- Contract tests: To verify that the test doubles used in the unit and component tests are behaving the same as an actual dependency would. Note: contract verification files are often shared between producers and consumers of the contract.
Check out this how to guide to learn how to implement this pattern.