Introduction
Clean Architecture (Uncle Bob) organizes ShopNest enterprise apps so business rules never depend on EF Core, UI, or email — only the reverse. Dependencies point inward toward the Domain.
After this article you will
- Map Domain, Application, Infrastructure, Presentation layers
- Apply the Dependency Rule with project references
- Place entities, use cases, and EF in correct layers
- Wire DI across layer boundaries
- Compare Clean Architecture to traditional N-tier
Prerequisites
- Article 43 — SignalR — Real-Time Web Applications
- ShopNest API, EF Core, and DI from prior modules
Concept deep-dive
┌─────────────────────────────────────┐
│ Presentation (Web API, MVC) │
├─────────────────────────────────────┤
│ Infrastructure (EF, Email, Files) │
├─────────────────────────────────────┤
│ Application (Use cases, DTOs, Val) │
├─────────────────────────────────────┤
│ Domain (Entities, Events, Interfaces)│ ← no outward deps
└─────────────────────────────────────┘
Domain: Task, Project entities; ITaskRepository interface.
Application: CreateTaskCommand, handlers, validators.
Infrastructure: TaskRepository, ShopNestDbContext implements interfaces.
Presentation: TasksController calls MediatR or application services.
// Domain — zero NuGet except maybe abstractions
public interface ITaskRepository
{
Task<TaskItem?> GetByIdAsync(Guid id, CancellationToken ct);
Task AddAsync(TaskItem task, CancellationToken ct);
}
// Infrastructure references Domain + Application
public class EfTaskRepository : ITaskRepository { ... }
Project references: Web → Application → Domain; Infrastructure → Application + Domain. Web must NOT reference Infrastructure types in controllers — only register via DI extension.
Hands-on — ShopNest Enterprise Task Management System
- Solution: ShopNest.Domain, .Application, .Infrastructure, .Web.
- CreateTask use case in Application; EF repo in Infrastructure.
- AddInfrastructure(this IServiceCollection) extension in Web Program.cs.
- Verify Domain project has no reference to EF or ASP.NET.
Common errors & best practices
- DbContext in Domain — violates dependency rule.
- Controllers calling _context directly — skip Application layer.
- Over-engineering simple CRUD — Clean Architecture pays off on complex domains.
Interview questions
Q: Dependency Rule?
A: Source code dependencies only point inward — outer layers implement inner interfaces.
Q: Clean vs N-tier?
A: N-tier is technical layers; Clean is business-centric with domain at center.
Q: Where do DTOs live?
A: Application layer (use case input/output), not Domain.
Summary
- Domain has no framework dependencies
- Application orchestrates use cases
- Infrastructure is pluggable via interfaces
- ShopNest task management scales with team boundaries
Previous: SignalR — Real-Time Web Applications
Next: CQRS Pattern with MediatR
FAQ
Clean Architecture vs Onion?
Same family of ideas — concentric layers, inward dependencies.
One DbContext per solution?
Typically in Infrastructure; Application defines repository contracts.