Volver al inicio

DDD en ASP.NET: problemas de escalabilidad después de 30 agregados

En proyectos ASP.NET con más de 30 agregados, DDD provoca degradación del rendimiento debido a consultas pesadas de EF Core, explosión de especificaciones y complejidades de transacciones. Análisis de problemas y recomendaciones para enfoques híbridos: CQRS, Vertical Slices.

¿Por qué falla DDD en grandes proyectos ASP.NET con 30+ agregados?
Advertisement 728x90

Escalando DDD en ASP.NET: Problemas más allá de 30 agregados

Cuando un proyecto supera los 30 agregados en ASP.NET con Entity Framework Core, el principio "una consulta — un agregado" genera problemas críticos de rendimiento. Cada agregado requiere carga completa con objetos anidados, generando consultas SQL con numerosos JOINs. Esto se vuelve especialmente problemático en sistemas ERP o marketplaces donde los gráficos de objetos alcanzan 5–6 niveles de anidamiento.

Una consulta típica para el agregado Order se ve así:

var orders = await context.Orders
    .Include(o => o.Customer)
        .ThenInclude(c => c.Address)
    .Include(o => o.Customer)
        .ThenInclude(c => c.Contacts)
    .Include(o => o.Items)
        .ThenInclude(i => i.Product)
            .ThenInclude(p => p.Category)
    .Include(o => o.Items)
        .ThenInclude(i => i.Discount)
    .ToListAsync();

El SQL resultante contiene decenas de LEFT JOINs, ralentizando significativamente la ejecución. Actualizar un solo campo en el encabezado de una orden obliga a cargar todos los OrderItems como parte del agregado, agravando aún más la sobrecarga de rendimiento.

Google AdInline article slot

Crecimiento explosivo de especificaciones y sus límites

El patrón Specification encapsula la lógica de consulta, pero con 30+ agregados, la colección de clases Specification puede crecer hasta cientos de archivos. La composición mediante And/Or genera SQL ineficiente debido a la dependencia de IQueryable en EF Core.

Desafíos clave:

  • Específico del ORM: Las especificaciones no funcionan con Dapper o gRPC sin reescribir.
  • Composición compleja: Escenarios del mundo real con roles, estados y zonas horarias se vuelven intratables.
  • Sobrecarga de abstracción: El tiempo invertido en abstracciones supera al dedicado a implementar la lógica de negocio real.

Transacciones entre agregados y sobrecarga de infraestructura

El DbContext con ámbito en ASP.NET Core funciona bien para Unit of Work en proyectos pequeños. En sistemas grandes, los flujos de trabajo comerciales suelen requerir actualizaciones simultáneas en 5+ agregados: colocar una orden, procesar un pago, reservar inventario y crear una tarea en centro de llamadas.

Google AdInline article slot

Las soluciones disponibles contradicen los principios de DDD:

  • Transacción en base de datos única — crea servicios Dios y viola los límites de los agregados.
  • Sagas distribuidas o patrón Outbox — aumentan la complejidad hasta 10 veces.

Como resultado, el 70% del código se convierte en glue de infraestructura para sincronización, no en lógica de negocio.

Navegación de código: Miles de archivos y iteraciones lentas

La estructura DDD (API/Application/Domain/Infrastructure + Features) genera más de 1.000 archivos con 30+ agregados. Cambiar un campo de una entidad afecta:

Google AdInline article slot
  • Entidad de dominio
  • Configuración Fluent API
  • Migración
  • Comando
  • Validador (FluentValidation)
  • Handler
  • DTO
  • Mapper (AutoMapper)
  • Specification
  • Pruebas

Esto ralentiza drásticamente el desarrollo, complica la incorporación y dificulta la mantenibilidad a largo plazo.

Lo que realmente importa

  • Rendimiento: Operaciones Include/ThenInclude pesadas generan SQL ineficiente, haciendo que los tiempos de respuesta de la API crezcan exponencialmente.
  • Especificaciones: No escalan, están atadas a EF Core y la composición lleva a errores.
  • Transacciones: Operaciones entre agregados obligan a compromisos entre ideales de DDD y necesidades reales del negocio.
  • Tamaño del códigobase: Más de 1.000 archivos ralentizan las iteraciones entre un 50% y un 70%.
  • Enfoque híbrido: Aplicar DDD solo en el núcleo; usar CQRS y Slices Verticales para temas periféricos.

Recomendaciones para la migración

Para proyectos con 30+ agregados, adopte arquitecturas híbridas:

  • CQRS: Separe comandos de consultas; use modelos de lectura sin cláusulas Include.
  • Slices Verticales: Agrupe el código por funcionalidad, minimizando la complejidad de capas.
  • Diseño por Slices de Funcionalidad: Logre modularidad sin arquitecturas rígidas tipo cebolla.

Estos enfoques preservan los principios de DDD en dominios complejos mientras simplifican todo lo demás.

— Editorial Team

Advertisement 728x90

Leer después