Onion Architecture
Concentric layers with the domain model at the center; dependencies point inwards and infrastructure sits at the edge.
Context
Proposed by Jeffrey Palermo in 2008, before Clean Architecture. It starts from a critique of classic layered architecture: the domain ended up depending on the data layer, so the database was the real center of the system.
Problem
In a traditional layered architecture (UI → Business → Data), the business layer references data access. Changing the ORM or testing business logic without a database becomes costly.
Solution
Concentric layers with a single rule: code can only depend on inner layers.
┌───────────────────────────────────────────────┐
│ UI · Infrastructure · Tests │ ← Outer (details)
│ ┌─────────────────────────────────────────┐ │
│ │ Application services │ │
│ │ ┌───────────────────────────────────┐ │ │
│ │ │ Domain services │ │ │
│ │ │ ┌─────────────────────────────┐ │ │ │
│ │ │ │ Domain model │ │ │ │ ← Center
│ │ │ │ (entities, value objects) │ │ │ │
│ │ │ └─────────────────────────────┘ │ │ │
│ │ └───────────────────────────────────┘ │ │
│ └─────────────────────────────────────────┘ │
└───────────────────────────────────────────────┘
- Domain model (center): entities and value objects, no dependencies.
- Domain services: rules that do not belong to a single entity. Repository interfaces live here too.
- Application services: orchestrate use cases.
- Outside: UI, persistence, external services and tests. They implement the interfaces defined inwards.
#Typical .NET structure
CSHARP
src/
├── Core/
│ ├── Domain/ ← Entities, value objects, repository interfaces
│ └── Application/ ← Application services, DTOs
├── Infrastructure/ ← EF Core, HTTP clients, messaging
└── Web/ ← API/UI, DI composition
#What sets it apart
- It is the one that most emphasizes the domain model as the center and the split between domain and application services.
- Less prescriptive than Clean: no "interface adapters" layer and no rules on how data travels between layers.
- More structured than Hexagonal: it defines internal layers, not just inside/outside.
- In practice, many .NET templates called "Clean Architecture" are strictly Onion:
Domain,Application,Infrastructure,Web.
See the full comparison.
When NOT to use it
- CRUD applications without a rich domain.
- If the team can't tell a domain service from an application service: layers become folders with no meaning.
Tradeoffs
| Pro | Con |
|---|---|
| Domain independent of persistence | More projects and mappings |
| Strong alignment with DDD | The domain service / application service boundary confuses |
| Testable without infrastructure | Same idea as Hexagonal/Clean with different vocabulary: easy to over-debate names |
#architecture #onion #ddd