Cómo estructurar un proyecto .NET usando Clean Architecture paso a paso

Cómo estructurar un proyecto .NET usando Clean Architecture paso a paso

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.

Deja un comentario