This is a project I've decided to make in order to show-case the depth of domain-driven design and how it tackles complexity in the heart of software.
I hope that this project can help someone getting started with Domain-Driven design, to sort of grasp ideas that they may have missed out on.
I've also been writing a blog series about Domain-Driven design that's quite provocative but very informative. Also please understand that there many different ways of solving problems in code, and mine isn't necessarily what I think is the "best" or the "only" way, its rather a way, the way I chose to tackle this.
Note: I have severely over-complicated the design in this project to try and show difficult concepts and capture the depth of domain-drivne design. Much of this work can be simplified and not every project, in fact most (small-scale) projects do not warrant the use of Domain-Driven design, let alone clean-architecture.
The overall business problem (space), aka the domain, that we will be focusing on is a business that rents out cars to customers. It may seem straight-forward at first, however, this can be a very complicated domain, depending on how deep we go. There are many invariants and state transitions that require cross-context communication.
- Strategic Design (Subdomains, BoundedContexts, ContextMapping)
- Tactical Design (AggregateRoots, Entities, ValueObjects)
- Event-Driven Architecture (Domain Events)
- CQRS
- ... and more
Domain-Driven Design is not an architectural pattern or a folder structure but rather a way of thinking that encourages modelling code based on the business.
There are many different ways of applying this in terms of code structure and there isn't a "best" way, but for the purpose of this project, I will be using Clean Architecture, an evolution of the Onion architecture that encourages inward-pointing dependencies, adapted by Robert C. Martin in the book "Clean Code".
All of the different variations: clean architecture, onion, ports-and-adapters, hexagonal, etc. are a variation, different visualization, or cosmetic differences of two principles regarding Dependency Inversion as a foundational:
- Abstractions should not depend upon details; details should depend upon abstractions.
- Higher-level modules should not depend upon lower-level modules; both should depend upon abstractions.
Folder structure:
π src/
βββ π₯ Demo.SharedKernel/
β βββ ...
βββ π¦ Demo.Domain/
β βββ ...
βββ π Demo.Application/
β βββ ...
βββ π οΈ Demo.Infrastructure/
β βββ ...
βββ π Demo.WebApi/
βββ ...
All contributions are welcome
Here are some related projects:
Event-Sourcing: A Portfolio Project (coming soon)
Vertical-Slice Architecture (coming soon)
Microservices with .NET (coming soon)
