Clean Architecture
Organiza el código en capas concéntricas donde el dominio es el centro y nada de fuera lo toca.
Contexto
Quieres aislar las reglas de negocio de detalles técnicos (framework, DB, UI) para poder cambiarlos sin reescribir el dominio.
Problema
Cuando el dominio depende de EF, ASP.NET o un broker concreto, los cambios técnicos rompen la lógica de negocio.
Solución
Capas concéntricas con la regla de dependencia: las dependencias apuntan hacia el centro, nunca hacia fuera.
┌──────────────────────────────────────┐
│ Frameworks & Drivers (Web, EF, MQ) │
│ ┌──────────────────────────────┐ │
│ │ Interface Adapters (DTOs, │ │
│ │ Controllers, Presenters) │ │
│ │ ┌──────────────────────┐ │ │
│ │ │ Use Cases (App) │ │ │
│ │ │ ┌──────────────┐ │ │ │
│ │ │ │ Entities │ │ │ │
│ │ │ └──────────────┘ │ │ │
│ │ └──────────────────────┘ │ │
│ └──────────────────────────────┘ │
└──────────────────────────────────────┘
#Reglas
- Dominio puro: sin
using Microsoft.EntityFrameworkCore, sin atributos web, sinDateTime.Now. - Casos de uso orquestan; no contienen reglas de dominio.
- Interfaces de salida (repositorios, services) viven en la capa Application, las implementan las capas externas (DI inversion).
#Estructura típica
CSHARP
src/
├── Domain/ ← Entidades, VOs, eventos, reglas. CERO dependencias.
├── Application/ ← Casos de uso, ports (IRepository, IClock). Depende solo de Domain.
├── Infrastructure/ ← EF, HTTP, MQ. Implementa los ports de Application.
└── Web/ ← ASP.NET. Compone el grafo DI.
// Application define el "puerto"
public interface IOrderRepository { Task<Order?> GetAsync(Guid id); }
// Infrastructure lo implementa
public class EfOrderRepository : IOrderRepository { /* ... */ }
// Web lo registra
services.AddScoped<IOrderRepository, EfOrderRepository>();Cuándo NO aplicarlo
- Microservicios pequeños o scripts: la ceremonia mata el ROI.
- Equipos sin disciplina para mantener las dependencias correctas.
Tradeoffs
| Pro | Contra |
|---|---|
| Dominio testeable sin infra | Más proyectos y boilerplate |
| Cambiar EF por Dapper sin tocar dominio | Mapeos extra entre capas |
| Encaja perfectamente con DDD | Curva de aprendizaje |
#architecture #clean #ddd