<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Beto Ramirez</title>
    <description>The latest articles on DEV Community by Beto Ramirez (@betoramiz).</description>
    <link>https://dev.to/betoramiz</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F122575%2F7a47e6b0-caa1-45b5-ba13-09e5afb012bd.jpg</url>
      <title>DEV Community: Beto Ramirez</title>
      <link>https://dev.to/betoramiz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/betoramiz"/>
    <language>en</language>
    <item>
      <title>CoreDriven: Un Template de Arquitectura Limpia en .NET para Acelerar tu Desarrollo</title>
      <dc:creator>Beto Ramirez</dc:creator>
      <pubDate>Sun, 10 Aug 2025 22:07:02 +0000</pubDate>
      <link>https://dev.to/betoramiz/coredriven-un-template-de-arquitectura-limpia-en-net-para-acelerar-tu-desarrollo-3691</link>
      <guid>https://dev.to/betoramiz/coredriven-un-template-de-arquitectura-limpia-en-net-para-acelerar-tu-desarrollo-3691</guid>
      <description>&lt;p&gt;Para cualquier desarrollador de .NET, iniciar un nuevo proyecto implica una serie de decisiones cruciales sobre la arquitectura. ¿Cómo aseguramos que la aplicación sea mantenible, escalable y, sobre todo, fácil de probar? La Arquitectura Limpia (Clean Architecture) nos ofrece una solución robusta, y con el template CoreDriven, he querido llevar esa implementación un paso más allá.&lt;/p&gt;

&lt;p&gt;Este post explora las características de &lt;a href="https://www.netmentor.es/entrada/core-driven-architecture" rel="noopener noreferrer"&gt;Core-Driven&lt;/a&gt;, un template de proyecto en .NET Core diseñado para programadores que buscan una base sólida y moderna para sus aplicaciones.&lt;/p&gt;

&lt;h3&gt;
  
  
  El Fundamento: Arquitectura Limpia
&lt;/h3&gt;

&lt;p&gt;CoreDriven se basa en los principios de la Arquitectura Limpia, garantizando una clara separación de responsabilidades. El dominio y la lógica de negocio (los casos de uso) están en el centro, sin dependencias de frameworks externos como Entity Framework o ASP.NET Core.&lt;/p&gt;

&lt;p&gt;Esto se traduce en beneficios directos:&lt;/p&gt;

&lt;p&gt;Independencia: Tu lógica de negocio no sabe nada sobre la base de datos, la UI o cualquier servicio externo.&lt;/p&gt;

&lt;p&gt;Testabilidad: Probar las reglas de negocio se vuelve trivial, ya que no requieren un entorno web o una base de datos activa.&lt;/p&gt;

&lt;p&gt;Mantenibilidad: Cambiar un detalle de infraestructura (como pasar de SQL Server a PostgreSQL) no afecta al corazón de tu aplicación.&lt;/p&gt;

&lt;h3&gt;
  
  
  Casos de Uso, una Sintaxis más Limpia
&lt;/h3&gt;

&lt;p&gt;Una de las decisiones de diseño en CoreDriven es cómo se estructuran los casos de uso (Use Cases). En lugar de usar una sola clasepara multiples funcionalidades, hacemos uso de una clase para solamente una solan funcinalidad, esto hara que el caso de uso tenga una forma lógica y concisa.&lt;/p&gt;

&lt;p&gt;Observa la diferencia. La implementación de un caso de uso se agrupa dentro de un solo archivo, mejorando la cohesión y la legibilidad.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8x7y35nehi852s9esyu9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8x7y35nehi852s9esyu9.png" alt="Use-Case" width="578" height="540"&gt;&lt;/a&gt;&lt;br&gt;
Este enfoque no solo reduce el número de archivos, sino que también hace que la navegación y la comprensión del flujo de una feature sean mucho más intuitivas.&lt;/p&gt;

&lt;p&gt;Ahora bien, en la capa de casos de uso podemos agruparlos con un nombre descriptivo que nos diga exactamente que es lo que el caso de uso resulve.&lt;br&gt;
Por ejemplo, en un TodoList, el caso de uso de creacion puede contener los archivos de Creacion del Todo, el Request, Response y las validaciones.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdf6f99h6hm22ilkfbi2n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdf6f99h6hm22ilkfbi2n.png" alt="Folder-structure" width="191" height="212"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Y asi podemos listar todos los casos de uso para la entidad Todo.&lt;/p&gt;

&lt;p&gt;La agrepacion de todos los casos de uso correspondiente a Todo la haremos con record que contega todos los casos de uso y que ademas implmente la interfaz IUseCaseRepository.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz5kinps42tnl4jwdqol4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz5kinps42tnl4jwdqol4.png" alt="usecase-repository" width="613" height="70"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Inyección de Dependencias Automática con Scrutor.
&lt;/h3&gt;

&lt;p&gt;Configurar la inyección de dependencias puede ser tedioso. Registrar cada servicio y su interfaz (services.AddScoped()) en proyectos grandes consume tiempo y es propenso a errores.&lt;/p&gt;

&lt;p&gt;Con este enfoque CorDriven camos a hacer uso de Scrutor, una pequeña pero potente librería que automatiza este proceso mediante el escaneo de ensamblados. Con unas pocas líneas de código, todos tus servicios, handlers y validadores de FluentValidation quedan registrados.&lt;/p&gt;

&lt;p&gt;Vamos a definir dos interfaces que solo seran indicadores para que Scrutor sepa donde buscar.&lt;/p&gt;

&lt;h5&gt;
  
  
  La interfaz IUseCase y la interfaz IUseIUseCaseRepository
&lt;/h5&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3re0pyfbaxjz9tsdjmhf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3re0pyfbaxjz9tsdjmhf.png" alt="interfaces" width="285" height="119"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ahora cada uno de nuestros casos de uso pueden hacer uso de la interfaz IUseCase y el record que agrupa a todos los use cases hara uso de la interfaz IUseCaseRepository.&lt;/p&gt;

&lt;p&gt;Esto hara que la inyeccion de dependencias con Scrutor sea muy simple:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjyh9lx2y5w02aj13r53w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjyh9lx2y5w02aj13r53w.png" alt="Scrutor" width="661" height="217"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Pruebas Unitarias Simples y Confiables.
&lt;/h3&gt;

&lt;p&gt;Gracias a la arquitectura desacoplada, probar nuestros casos de uso es increíblemente fácil. No necesitamos mocks complejos ni configuraciones aparatosas. La lógica de negocio está aislada y lista para ser validada.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvy2oy4i3fl7tm477zedp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvy2oy4i3fl7tm477zedp.png" alt="UnitTest" width="800" height="307"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La prueba es limpia, legible y se enfoca exclusivamente en la lógica del caso de uso, validando su comportamiento de forma aislada.&lt;/p&gt;

&lt;p&gt;Si buscas una base sólida, moderna y bien estructurada para tu próximo proyecto en .NET, te invito a que le des una oportunidad a CoreDriven.&lt;/p&gt;

&lt;p&gt;Visita el repositorio en GitHub: &lt;a href="https://github.com/betoramiz/coredriven" rel="noopener noreferrer"&gt;https://github.com/betoramiz/coredriven&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;¡Clónalo y empieza a construir!&lt;/p&gt;

&lt;p&gt;Cualquier feedback, sugerencia o contribución es más que bienvenida. ¡Espero que este template te ayude a construir software increíble!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Separando la logica de la capa de negocios en casos de uso.</title>
      <dc:creator>Beto Ramirez</dc:creator>
      <pubDate>Wed, 09 Apr 2025 20:39:35 +0000</pubDate>
      <link>https://dev.to/betoramiz/separando-la-logica-de-la-capa-de-negocios-en-casos-de-uso-48ka</link>
      <guid>https://dev.to/betoramiz/separando-la-logica-de-la-capa-de-negocios-en-casos-de-uso-48ka</guid>
      <description>&lt;p&gt;En este post quiero explicar como se puede lograr una separacion entre a logica de la aplicacion o capa de reglas de negocio del resto de las capas de la arquitectura que estemos utilizando.&lt;/p&gt;

&lt;p&gt;El codigo completo lo puedes encontrar &lt;a href="https://github.com/betoramiz/usecaseDispatcher" rel="noopener noreferrer"&gt;Aqui&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  El problema.
&lt;/h2&gt;

&lt;p&gt;He tenido la oportunidad de trabajar en distintos tipos de proyectos, algunos muy grandes, otros pequeños y otros de tamaño medio.&lt;/p&gt;

&lt;p&gt;En mucho de ellos he visto la implementacion de la capa de logica de negocios donde se defina una interfaz que contiene la definicion de las acciones de de ese servicio.&lt;/p&gt;

&lt;p&gt;Supongamos que tenemos una aplicacion que tiene la entidad cliente y en la capa donde vive nuestra logica de aplicacion tenemos una interfaz que define todas las acciones del cliente.&lt;/p&gt;

&lt;p&gt;Algo como esto.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu1coxo9duijlrcchpzg7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu1coxo9duijlrcchpzg7.png" alt="IClientServiceInterface" width="410" height="238"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dentro de esta interfaz podemos agregar cuantos metodos necesitemos y entre mas metodos agregemos, la clase que implemente dicha interfaz sera un mounstroo de muchisimas lineas de codigo dificil de leer. y de mantener.&lt;/p&gt;

&lt;p&gt;Esto no esta mal perse, ya que tenemos una interfaz que despues podemos inyectar en la capa superior que seria la capa de presentacion, nos permite hacere referencia a una abstracion, nos permitira tener mas facilidad de hacer unit testing y en general seguimos principios solid.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxg6tcybev61em7wshw1c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxg6tcybev61em7wshw1c.png" alt="Client Controller with IClientService injected" width="529" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pero esto tambien es mejorable y aqui es donde viene una propuesta de solucion.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solucion.
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Partiendo la interfaz
&lt;/h3&gt;

&lt;p&gt;En la imagen anterior, la interfaz IClient implementa el principio de Single Resposanbility. &lt;br&gt;
Tenemos una interfaz que tiene muchos metodos de la logica de aplicacion pero aun podemos tener mayor granularidad.&lt;br&gt;
En lugar de tener una unica interfaz, podemos separarla en partes y generar una clase para cada accion, es decir, una clase por cada metodo definido en la interfaz.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8rxjqt1qyh12vgne5a4a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8rxjqt1qyh12vgne5a4a.png" alt="interfaces separeted" width="655" height="825"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cada una de estas clases hacen referencia a un case de uso enconcreto de nuestra capa de negocios y estan perfectamente separadas.&lt;/p&gt;

&lt;p&gt;Ahora, estas clases no implementan ninguna interfaz. Lo cual no esta mal por que aun asi podemos seguid inyectando cada una de estas clases en .NET pero no es lo ideal ya que estariamos dependiendo de una clase concreta y no de una abstraccion.&lt;/p&gt;

&lt;h3&gt;
  
  
  Agregando IUseCase
&lt;/h3&gt;

&lt;p&gt;Para solucionarlo vamos a crear una interfaz que la nombraremos IUseCase y cada una de nuestras clases podras implementar esta interfaz.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbs6v8if1b5ozgdef2la9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbs6v8if1b5ozgdef2la9.png" alt="IUseCase" width="656" height="299"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ahora si, nuestro caso de uso ya puede ser inyectado de mejor manera en nuestro controlador y obtener el cliente por Id.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faiikgdwx8r53od1hcga3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faiikgdwx8r53od1hcga3.png" alt="IUseCase In controller" width="419" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Convirtiendo el IUseCase en generico.
&lt;/h3&gt;

&lt;p&gt;Bien, ahora con este diseño nos enfretamos a otro "problema". Y es que tenemos que crer una interfaz por cada caso de uso, definir los parametros que recibe y el tipo de la respuesta de cada metodo, ademas de eso el nombre que tendra el metodo que ejecutara la logica de aplicacion podria tener el nombre que sea.&lt;/p&gt;

&lt;p&gt;Para solucionar estos inconvenientes haremos uso de los Generics de C# y vamos a convertir a nuestra interfac IUseCase en una interfaz generica que tenga como entrada un tipo y que tenga una salida.&lt;/p&gt;

&lt;p&gt;Ademsa de todo esto, tambien vamos a definir otra interfaz IRequest que servira para marcar a los datos de entrada de nuesto Caso de uso.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4q96j64iyc1qqsnsgqxr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4q96j64iyc1qqsnsgqxr.png" alt="Image description" width="410" height="177"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Con este caso de uso generico ya podemos estandarizar el nombre del metodo que ejecutara la logica de negocio en cada caso de uso, ademas, con la interfaz IRequest definimos que cada caso de uso tiene una entrada y genera una salida.&lt;/p&gt;

&lt;p&gt;La implementacion de el caso de uso de obtener un cliente por Id quedaria de la siguiente manera:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flp065rf95hqp4xz319ig.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flp065rf95hqp4xz319ig.png" alt="Image description" width="654" height="331"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Con esto, no necesitamos crear una interfaz para cada caso de uso, ahora estamos reutilizando una unica interfaz generica que nos ayudara a implementar la logica de negocio.&lt;/p&gt;

&lt;p&gt;Y para hacer uso del case de uso tendriams que inyectar la interface IUseCase de la siguiente manera:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6ewtmy5nocakxqcv68rq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6ewtmy5nocakxqcv68rq.png" alt="Image description" width="583" height="336"&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Hasta aqui tenemos una separacion de la logica de negocios de nuestro controller y ademas cada caso de uso esta en una clase separada lo que hace que queca caso de uso tenga una resposabilidad unica.&lt;/p&gt;

&lt;p&gt;Seguimos manteniendo una inversion de control mediante la inyeccion de dependencias y segumos mantiendo la testeabilidad de la capa de negocios.&lt;/p&gt;

&lt;h2&gt;
  
  
  Despachador de Casos de uso.
&lt;/h2&gt;

&lt;p&gt;Ok, considero que la implementacinon hasta este punto esta bien.&lt;/p&gt;

&lt;p&gt;Si la logica de negocio empieza a crecer en numero de casos de uso, entonces nos tocara injectar un monton de estos en el contolador, no es un lio pero quiza el codigo no se vea tan "limpio" con eso.&lt;/p&gt;

&lt;p&gt;Entonces, que tal que agregamos un despachador de casos de uso, es decir, una capa extra que internamente resuelva cual es el caso de uso que tiene que utilizar dependiendo de el request y el response:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwe5wc8rgvpv063wgvs52.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwe5wc8rgvpv063wgvs52.png" alt="dispatcher" width="800" height="785"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Esta seria la implementacion de nuestro use case dispatcher.&lt;/p&gt;

&lt;p&gt;Internamente hace uso del Service Provider de .net para poder entregarnos el caso de uso correcto.&lt;/p&gt;

&lt;p&gt;Ademas, podemos loguear errores cuando se ejecute el metodo ExecuteAsync de cada caso de uso.&lt;/p&gt;

&lt;p&gt;Y la implementacion en cada Controller seria algo asi:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxzdlczchqknfmubba6ea.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxzdlczchqknfmubba6ea.png" alt="dispatcher in controller" width="693" height="352"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
