Cuando una aplicación crece, mantener el código organizado se convierte en un desafío. Es común encontrar proyectos donde la lógica de negocio, el acceso a datos y la interfaz de usuario están mezclados, dificultando el mantenimiento y la escalabilidad. Para solucionar este problema, muchos equipos de desarrollo utilizan Clean Architecture, un enfoque que permite crear aplicaciones más robustas, fáciles de probar y preparadas para evolucionar con el tiempo.
En el ecosistema de ASP.NET Core y .NET moderno, Clean Architecture se ha convertido en uno de los patrones más recomendados para aplicaciones empresariales.
¿Qué es Clean Architecture?
Clean Architecture es una metodología propuesta por Robert C. Martin que organiza el software en capas independientes. Su objetivo principal es que las reglas de negocio no dependan de frameworks, bases de datos o tecnologías externas.
La idea central es que las dependencias siempre apuntan hacia el núcleo de la aplicación, nunca al revés.
Beneficios principales
- Mayor mantenibilidad.
- Código más fácil de probar.
- Separación clara de responsabilidades.
- Menor dependencia de tecnologías específicas.
- Escalabilidad para proyectos grandes.
Estructura recomendada del proyecto
Una solución basada en Clean Architecture suele dividirse en cuatro proyectos principales:
MiAplicacion.sln
├── MiAplicacion.Domain
├── MiAplicacion.Application
├── MiAplicacion.Infrastructure
└── MiAplicacion.WebAPI
1. Domain (Dominio)
Es el corazón de la aplicación.
Contiene:
- Entidades
- Enumeraciones
- Objetos de valor
- Interfaces de dominio
- Reglas de negocio
Ejemplo:
public class Product
{
public Guid Id { get; set; }
public string Name { get; set; } = string.Empty;
public decimal Price { get; set; }
}
Esta capa no debe depender de ninguna otra.
2. Application (Aplicación)
Aquí se implementan los casos de uso del sistema.
Contiene:
- DTOs
- Commands
- Queries
- Validaciones
- Interfaces de repositorios
- Servicios de aplicación
Ejemplo de interfaz:
public interface IProductRepository
{
Task<Product?> GetByIdAsync(Guid id);
}
La capa Application conoce al Domain, pero no a Infrastructure.
3. Infrastructure (Infraestructura)
Implementa los detalles técnicos.
Contiene:
- Entity Framework Core
- Acceso a bases de datos
- Servicios externos
- Integraciones
- Repositorios concretos
Ejemplo:
public class ProductRepository : IProductRepository
{
private readonly AppDbContext _context;
public ProductRepository(AppDbContext context)
{
_context = context;
}
public async Task<Product?> GetByIdAsync(Guid id)
{
return await _context.Products.FindAsync(id);
}
}
Esta capa depende de Application y Domain.
4. WebAPI (Presentación)
Es la puerta de entrada de la aplicación.
Contiene:
- Controllers
- Middlewares
- Configuración
- Autenticación
- Swagger
Ejemplo:
[ApiController]
[Route("api/products")]
public class ProductsController : ControllerBase
{
[HttpGet("{id}")]
public async Task<IActionResult> Get(Guid id)
{
return Ok();
}
}
La API solo debe coordinar solicitudes y respuestas, evitando colocar lógica de negocio aquí.
Flujo de dependencias
La regla más importante es:
WebAPI
↓
Application
↓
Domain
Infrastructure
↓
Application
↓
Domain
Nunca debe ocurrir algo como:
Domain → Infrastructure
Porque el núcleo del negocio no debe conocer detalles técnicos.
Implementando CQRS con MediatR
Una práctica muy común es combinar Clean Architecture con el patrón CQRS.
Ejemplo de Command:
public record CreateProductCommand(
string Name,
decimal Price
);
Handler:
public class CreateProductHandler
{
public async Task Handle(
CreateProductCommand command)
{
// lógica de negocio
}
}
Esta separación mejora la organización y facilita las pruebas unitarias.
Registro de dependencias
En Program.cs se registran los servicios:
builder.Services.AddApplication();
builder.Services.AddInfrastructure(
builder.Configuration);
Cada capa expone métodos de extensión para registrar sus propios servicios, manteniendo el código limpio y desacoplado.
Buenas prácticas
- Mantener entidades simples y enfocadas.
- Utilizar DTOs para exponer datos.
- Aplicar validaciones con FluentValidation.
- Implementar CQRS en aplicaciones medianas y grandes.
- Evitar lógica de negocio en Controllers.
- Crear pruebas unitarias para Application y Domain.
- Mantener Infrastructure completamente desacoplada del negocio.
Clean Architecture es una de las mejores estrategias para desarrollar aplicaciones modernas con .NET. Aunque requiere una estructura inicial más elaborada que un proyecto tradicional, sus beneficios en mantenibilidad, escalabilidad y pruebas compensan ampliamente el esfuerzo. Al separar correctamente Domain, Application, Infrastructure y WebAPI, los equipos pueden construir soluciones empresariales sólidas, preparadas para crecer y adaptarse a nuevos requerimientos sin comprometer la calidad del código.

