Contenido del curso

Casos de uso en Clean Architecture con C#

Resumen

Los casos de uso en Clean Architecture son la forma que propone Robert Martin para organizar la capa de aplicación, encapsulando reglas de negocio específicas y coordinando el flujo entre la capa externa y el dominio. Si vienes de trabajar con capa de servicios, vas a notar similitudes inmediatas, y eso no es casualidad: la intención detrás es la misma, solo cambia la notación.

¿Qué es un caso de uso en Clean Architecture?

Un caso de uso representa una operación concreta que tu aplicación puede ejecutar, como registrarse en un curso, crear una orden o autenticar un usuario. Cada caso de uso vive como una clase independiente que coordina entidades, repositorios y servicios para cumplir un objetivo puntual.

Robert Martin distingue dos niveles de reglas de negocio: las que aplican a toda la empresa y se ubican en las entidades del dominio, y las específicas de una aplicación que viven en los casos de uso. En la práctica, cuando trabajas con un solo sistema, esa frontera se vuelve difusa y termina siendo más una guía que una regla estricta.

¿Para qué sirve un caso de uso? Coordina el flujo de datos desde la capa externa hacia las entidades de dominio y devuelve el resultado procesado a esa capa externa. Es el puente entre lo que pide el usuario y lo que ejecuta el dominio.

¿Cómo se estructura un caso de uso en código?

La convención más extendida es una clase por cada caso de uso, todas heredando de una clase base o implementando una interfaz común. Esa interfaz suele llamarse request handler y define el contrato que cualquier operación debe cumplir.

En el ejemplo en C# .NET que se revisa en clase [04:30], la estructura del proyecto core contiene varios elementos clave:

  • Contratos: interfaces para inyección de dependencias y clases base reutilizables.
  • DTOs: objetos para transportar datos entre la capa externa y el dominio.
  • Entidades: el modelo de dominio con sus reglas de negocio.
  • Casos de uso: clases que orquestan operaciones específicas como registrarse en un curso.

¿Cómo se implementa la interfaz IRequestHandler?

La interfaz IRequestHandler usa genéricos para definir que un caso de uso recibe una solicitud y devuelve una respuesta [05:40]. Cuando una clase la implementa, queda obligada a respetar esa firma, lo que da consistencia a toda la capa de aplicación.

Dentro del caso de uso encontrás dos piezas habituales:

  1. Inyección de dependencias en el constructor: el servicio de autenticación, los repositorios y otros colaboradores entran por aquí.
  2. Método handle: el punto de entrada que ejecuta la operación, valida permisos, accede al repositorio, procesa la información y produce un resultado.

¿En qué se diferencia un caso de uso de un servicio? En el fondo, no mucho. Ambos exponen operaciones del dominio a la capa externa. Cambia la notación y la convención de nombres, pero el resultado funcional es equivalente.

¿Por qué conviene una clase por caso de uso?

Tener una clase separada por operación te da una organización muy clara. Si necesitas modificar el flujo de registro en un curso, vas a un único archivo y no corres el riesgo de romper otras operaciones que viven en la misma clase. Esa separación reduce el acoplamiento y facilita las pruebas unitarias.

Y aquí viene lo interesante: esta granularidad también prepara el terreno para patrones como CQRS, donde cada comando o consulta es, en esencia, un caso de uso especializado.

¿Por qué encuentro nombres distintos para los casos de uso?

Clean Architecture deja varios detalles abiertos a la interpretación, así que la comunidad ha llenado esos vacíos con nombres distintos. Vas a encontrar el mismo concepto bajo varios sufijos:

  • Interactor: notación clásica que aparece en muchos ejemplos, incluido el de C# revisado.
  • Service: heredado de la capa de servicios tradicional.
  • Command handler: común en implementaciones que se acercan a CQRS.
  • Request handler: el nombre genérico que usa el ejemplo en C#.

No te enredes con el nombre. Lo importante es la intención: una clase por operación, con dependencias inyectadas y un método claro que ejecuta el flujo.

¿Qué hace el método handle dentro de un caso de uso?

El método handle es el corazón del caso de uso. Recibe la solicitud, valida con el servicio de autenticación si el usuario tiene permisos, consulta el repositorio para traer las entidades necesarias, ejecuta la lógica del dominio y devuelve una respuesta lista para la capa externa.

Esta secuencia se repite con variaciones en cualquier caso de uso bien diseñado, sin importar si lo llamás interactor, service o command handler. Te invito a clonar el repositorio del ejemplo en C#, compararlo con el caso anterior en Java y comentar qué diferencias notas en la organización entre ambos lenguajes.