Robert C. Martin’s “Clean Architecture” (or Onion/Hexagonal Architecture) is the gold standard for testable, maintainable enterprise systems. In this article, I will demonstrate how to structure a .NET 5 solution to enforce the Dependency Rule strictly.
The Dependency Rule
Source code dependencies must point only inward, toward high-level policies. The Inner circles (Domain) must not know anything about the outer circles (Database, Web, UI).
block-beta
columns 1
block:Layers
block:Infra
WebUI
Infrastructure
end
block:Core
Application
Domain
end
end
WebUI --> Application
Infrastructure --> Application
Application --> Domain
Infrastructure --> Domain
style Domain fill:#C8E6C9,stroke:#2E7D32
style Application fill:#E8F5E9,stroke:#43A047
style Infrastructure fill:#FFECB3,stroke:#FF6F00
style WebUI fill:#E1F5FE,stroke:#0277BD
Solution Structure
Create your solution with these 4 specific projects:
- Domain (Class Library): Enums, Value Objects, Domain Entities, Domain Exceptions. Dependencies: None.
- Application (Class Library): Interfaces (`IRepository`), DTOs, MediatR Handlers, Validators. Dependencies: Domain.
- Infrastructure (Class Library): EF Core DbContext, Email Service Implementation, Third Party API Clients. Dependencies: Application, Domain.
- WebUI (Web API): Controllers, Middlewares. Dependencies: Application, Infrastructure.
Dependency Injection Glue
The trick is how `WebUI` wires everything up without breaking the abstraction. We use Extension methods in each layer.
// Infrastructure/DependencyInjection.cs
public static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration config)
{
// Implementation details (EF Core) are hidden here
services.AddDbContext<AppDbContext>(opt =>
opt.UseSqlServer(config.GetConnectionString("Db")));
services.AddScoped<IOrderRepository, OrderRepository>();
return services;
}
This keeps `Startup.cs` clean: `services.AddApplication().AddInfrastructure(Configuration);`.
Discover more from C4: Container, Code, Cloud & Context
Subscribe to get the latest posts sent to your email.