Clean Architecture Dependency Rule in .NET
How the dependency rule protects the Ordering domain from infrastructure, frameworks, and delivery mechanisms.

The problem Clean Architecture solves
Many backend systems start clean but slowly collect infrastructure decisions inside business logic. Controllers know too much about persistence. EF Core entities become business models. Message broker details leak into use cases.
Clean Architecture exists to stop that drift. The core idea is simple: dependencies should point inward toward the domain, not outward toward frameworks.
The Ordering service example
In this .NET 8 architecture, Ordering is the service where Clean Architecture provides the most value. Orders usually contain business rules, lifecycle transitions, payment or fulfillment concerns, and consistency requirements that should not be tied to a specific database or API style.
The expected layer direction looks like this:
API / Adapters -> Application -> Domain
Infrastructure -> Application -> Domain
Domain -> no outer dependencies
The Domain layer should contain entities, aggregates, value objects, and invariants. It should not reference Infrastructure, Web, EF Core, SQL Server, RabbitMQ, or ASP.NET Core.
What belongs in each layer
The Application layer coordinates use cases. It can define commands, queries, handlers, abstractions, validators, and transaction boundaries. MediatR is useful here because it makes command and query flow explicit.
Infrastructure contains concrete details. EF Core repositories, SQL Server mappings, RabbitMQ publishers, external API clients, and configuration belong here because they are replaceable mechanisms.
Adapters translate the outside world into application requests. Controllers, Minimal APIs, gRPC endpoints, presenters, and request or response DTOs should remain thin.
What to audit in a real codebase
A clean folder structure is not enough. The real check is dependency direction.
- Verify Domain has no project reference to Infrastructure, API, Web, or messaging projects.
- Verify Application depends on abstractions instead of concrete persistence classes.
- Verify Infrastructure implements interfaces defined inward.
- Verify validation happens before bad requests reach the domain.
- Verify domain invariants still exist inside entities or aggregate behavior.
If all business rules live in handlers and the domain is only data properties, the architecture may be layered but not domain-centered.
Trade-offs engineers should accept
Clean Architecture adds ceremony. A small CRUD endpoint can require a request model, command, validator, handler, interface, implementation, mapper, and endpoint. That may be wasteful for simple services.
The pattern earns its cost when the business rules are long-lived, heavily tested, and likely to outlive infrastructure decisions. It is weaker when the service is mostly data entry with little behavior.
When to use it
Use Clean Architecture when domain correctness matters more than initial speed. Ordering, billing, inventory reservation, and approval workflows are common examples.
Avoid forcing it everywhere. Catalog reads, Basket feature slices, or small discount lookups may be better served by simpler patterns as long as boundaries remain clear and tests cover the important behavior.