Think about Database-centric (3 layer architecture) vs. Domain-centric architecture. The domain is essential. The database is a detail.
The key idea of the clean architecture is that the dependencies should be:
Domain(Entity) <- Application <- Presentation, Infrastructure, Persistance(DB)
So, The domain is independent of the application. Application is independent of persistence or infrastructure.
- Focus on domain
- Less coupling
- Allows for DDD
- Change is difficult
- Requires more thought.
- Initial higher cost
When to use domain-centric architecture? If the application is complex enough and long-lasting.
For me, the biggest question was on the application layer, which seems like doing everything except domain, infrastructure, and cross-cutting concerns.
The application layer can keep the independence by accessing all other layers through interfaces rather than implementation.
In other words, the implementation details sit on each infrastructure layer, service layer, etc, while the application layer only works with the high-level abstraction of interfaces.
This helps make the code testable. Given that the number one reason why Unit Test fails is the code is not testable which make the unit test difficult, costly, un-maintainable, making the application layer independent through the interface is the most important concept in the clean architecture.
In practice, the domain layer and cross-concern layer can sit in the same VS project because every other layer can depend on both layers. For example, in NopCommerce, both domain and cross-concern layer sit in Nop.Core project. This type of project normally named Core or Common.
Use complex domain when writing the state. Use direct query for performance when reading.
Type 1. Share the same database.
Type 2. Use a separate database for each and write for the best performance.
Type 3. Event Sourcing pattern. Write an event to the event store which does not contain a state. Read database contains state constructed from the event store.
- Lazy Loading
- Eager Loading
- Projection Loading -> Recommended way.
Query, differently from command, should bypass the domain model and use whatever the most efficient way to get the data directly from the database.