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

  1. Dominio puro: sin using Microsoft.EntityFrameworkCore, sin atributos web, sin DateTime.Now.
  2. Casos de uso orquestan; no contienen reglas de dominio.
  3. 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