Version A from lesson 4.10.2 showed what Microsoft's guide says about layers: the business logic depends on data access, and whoever wants to check it opens a database. The same guide also names the remedy, the Dependency Inversion Principle. If you apply it consistently, you end up at an architecture that has had several names over the years. In this lesson it is called what most templates for .NET call it today: onion and clean architecture.
You build version B of the follow-up with the domain in the middle, use cases as a project of their own and the infrastructure on the outside. Then comes the same change as in version A, and you measure the same things. One measuring point you take especially seriously this time: the types that only map. They are the price this style pays most visibly.
The domain in the middle
The onion architecture (Jeffrey Palermo) draws a program as an onion. In the middle lies the domain model, around it rings for domain services and application services, on the very outside the UI, the infrastructure and the tests. One rule holds the picture together: every ring may know only the rings further inside. What lies outside knows the middle; the middle knows nothing outside itself.
Microsoft's guide "Common web application architectures" (under Further reading) describes the same onion as a view of clean architecture: the business logic and the model of the application stand in the middle, and instead of the business logic depending on data access, the dependency is turned around. The infrastructure depends on the core. That works because the core defines interfaces and the infrastructure implements them. Two sentences from the guide are especially important for this lesson:
- UI and infrastructure both depend on the core, but not necessarily on each other.
- At compile time the UI works only with the interfaces of the core. At run time it still needs the classes of the infrastructure, and dependency injection connects the two at start.
The second sentence solves a puzzle that version A with PrepareFollowUps only sidestepped: who puts the parts together if nobody may know
them all? Answer: the composition root, Program.cs, and only it. For this the guide expressly allows the UI project to reference the
infrastructure project, with the request to use types from it only in the composition root.