Ideally, the solution should support the notion of screaming architecture - architecture that from the shear look of the code makes it abundantly clear what it is about, where it does it, and how it does it.
As Uncle Bob puts it: "Your architectures should tell readers about the system, not about the frameworks you used in your system."
The solution roughly consist of these components:
The refactored code is located exclusively in the src
folder (this folder). The remaining folders are unchanged from the original solution.
Use the main solution file ChampagneBC.sln when opening the solution in your IDE.
The solution displays a number of design choices:
- The domain model is the core of our software, and should not be spread across many different layers. It is therefore fully encapsulated in the src/Domain assembly
- Domain validation logic is implemented only once in domain aggregates and value objects, making it easy to comprehend and test
- The solution supports eventing on top of a Marten PostgreSQL database. In order to clearly segregate mutations (arising from commands) and queries, the solution adopts CQRS entirely to enable event publishing on distinct mutations.
- Commands are handled by Command Handlers in the src/Commands assembly
- Queries are encapsulated in the src/Projections assembly
- Events are published atomically internally inside the PublishingAggregateRepository
- Projections (e.g., readmodels) are eventually consistent by design, allowing for massive scalability on the read-side of the application.
The best way to get started is to read the unit test suites that outlines the invariants of the domain model: src/Domain.UnitTests.
Another place to explore is defintely the domain model itself and the value objects involved.
Most certainly! Just create an issue or a PR in this repo.