Como arquitetar um aplicativo com ASP. NET Core (Arquitetura Limpa) | Trevoir Williams | Skillshare
Buscar

Velocidad de reproducción


  • 0.5x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 2x

Arquitectura de ASP. Aplicación NET Core (arquitectura limpia)

teacher avatar Trevoir Williams, Jamaican Software Engineer

Ve esta clase y miles más

Obtenga acceso ilimitado a todas las clases
Clases enseñadas por líderes de la industria y profesionales activos
Los temas incluyen ilustración, diseño, fotografía y más

Ve esta clase y miles más

Obtenga acceso ilimitado a todas las clases
Clases enseñadas por líderes de la industria y profesionales activos
Los temas incluyen ilustración, diseño, fotografía y más

Lecciones en esta clase

    • 1.

      Introducción

      1:30

    • 2.

      Comprender la arquitectura limpia

      7:03

    • 3.

      Qué vamos a construir

      4:22

    • 4.

      Configuración de la solución

      2:55

    • 5.

      Crear el proyecto de dominio

      6:08

    • 6.

      Crear el proyecto de aplicación

      7:14

    • 7.

      Implementar la Automapper

      12:19

    • 8.

      Crea consultas con MediatR

      16:18

    • 9.

      Finalización de las consultas para MediatR

      7:42

    • 10.

      Crea comandos con MediatR

      12:35

    • 11.

      Terminar los comandos con MediatR

      21:39

    • 12.

      Agrega Validación

      27:27

    • 13.

      Agrega excepciones y objetos de respuesta personalizadas

      13:14

    • 14.

      Refactoring y consideraciones adicionales

      9:39

    • 15.

      Descripción de la sección

      1:46

    • 16.

      Agregar núcleo de el marco de la entidad

      5:37

    • 17.

      Implementar la capa de persistencia

      15:27

    • 18.

      Añade proyecto de Infrastructure (servicio de correo electrónico)

      15:59

    • 19.

      Crear y configurar la API de la aplicación

      11:44

    • 20.

      Implementar los controladores de la API finos

      14:56

    • 21.

      Terminar los controladores de la API finales

      4:29

    • 22.

      Datos de semena en las semillas

      4:47

    • 23.

      Revisión de Swagger API

      8:26

    • 24.

      Pruebas de unas: descripción de la sección

      3:23

    • 25.

      Prueba de la unidad para el código de la aplicación

      28:25

    • 26.

      Configuración de la proyecto ASP.NET MVC

      2:14

    • 27.

      Usar NSwag para el código de cliente API

      8:35

    • 28.

      Configurar los clientes de API y el código personalizado y el base

      14:18

    • 29.

      Instalación del servicio de gestión de los tipos de permisos

      12:11

    • 30.

      Configuración de la gestión de los tipos de Leave

      27:55

    • 31.

      Añade la autenticación de Json web en (JWT) a Json

      36:55

    • 32.

      Añade autenticación al proyecto web

      30:35

    • 33.

      Configuración de la dirección del permisos

      18:50

    • 34.

      Gestión : parte 1 - Empleador

      20:53

    • 35.

      Gestión : parte 2 - Admin

      24:29

    • 36.

      Unidad de trabajo para las operaciones de lotes

      8:40

    • 37.

      Gestión de excepciones de API

      13:36

    • 38.

      Manejo de la terminación de Token

      8:40

    • 39.

      Manejo de la terminación de Token

      13:51

    • 40.

      Mejorar la Auditoría de datos

      5:54

    • 41.

      Conclusión

      1:03

  • --
  • Nivel principiante
  • Nivel intermedio
  • Nivel avanzado
  • Todos los niveles

Generado por la comunidad

El nivel se determina según la opinión de la mayoría de los estudiantes que han dejado reseñas en esta clase. La recomendación del profesor o de la profesora se muestra hasta que se recopilen al menos 5 reseñas de estudiantes.

193

Estudiantes

--

Proyectos

Acerca de esta clase

Descripción

Crear una aplicación modular, probable y mantenible en . El núcleo de NET requiere una base sólida. La configuración de una arquitectura de una aplicación requiere foresight y mucha consideración ya que las decisiones tempranas tendrán un impacto con fácil se extiende y mantenía.

En la larga carrera, deben mantenerse las aplicaciones y en este caso, extender. Entre su diseño y la forma de escribiría el código que estaba escrito, tampoco es realmente posible y por lo que la aplicación necesita ser rediseñada y la versión de

¿Por qué la arquitectura SOLID

Cuando hablamos de la arquitectura SOLID y nos estamos referring a la no es una tarea directa. Las decisiones tomadas en el proceso pueden tener un gran impacto más tarde, y la importancia desempeñar un rol importante. Adoptar estas prácticas también puede contribuir a evitar los olor de código y refactoring y facilitar el desarrollo ágil más eficiente.

SOLID significa lo de lo siguiente:

  • S: principio de la responsabilidad única

  • O - principio abierto

  • L - Principio de la sustitución de Liskov

  • I - principio de segregación de la interfaz

  • D - principio de inversión de dependencia

En este curso, exploras los principios arquitectónicos básicos que ayudan con la creación de código sostenible. Luego, descubrirás cómo configurar una arquitectura de aplicación real con ASP.NET Core. Luego, aprenderás a conectar bloques diferentes y comunes como el correo común, la autenticación y tener una base para complementar otros servicios externos como necesario.

Cuando termines este curso, tendrás las habilidades y el conocimiento de crear una aplicación principal probable y la necesidad necesaria para diseñar la empresa de la mundo real. Aplicaciones del núcleo neto.

Construir una base fuerte Arquitectura limpia en la naturaleza:

  • Aprende la arquitectura limpia o la cebolla y las mejores prácticas

  • Aprende la segregación de la responsabilidad con la consulta con la consulta (CQRS)

  • Implementar el patrón Mediatr

  • Añade un servicio de correo electrónico con SendGrid

  • enfoque de diseño impulsado de dominio en la arquitectura de los software

  • Manejo y enrutado de excepciones eficientes

  • Implementar pruebas de la unidad

  • Gestión de errores globales con middleware y excepciones personalizadas

  • Agrega la validación con Validación con la Validación fluida

  • Construir un . API en base mos. y aplicación la UI MVC

  • Implementar la autenticación JWT(JSON

Contenido y descripción

Para tomar este curso, tendrás que tener algún conocimiento de él. Desarrollo núcleo de la base de redes en la red y C#.

Este es un curso huge Más de 10 horas de contenido premio, pero se dividió inteligentemente para destacar un conjunto de actividades relacionadas basadas en cada módulo en la aplicación que se construyas. También vamos a estudiar la solución de problemas y el régimen de los errores mientras avanzamos, aplicando las mejores prácticas, la escritura de la lógica eficiente y comprensión por qué los desarrolladores hacen lo hacen de tu forma funcionado. Tu conocimiento crecerán paso a paso, paso a paso, a través del curso y podrás ser el mejor que puedas ser.

No hacemos las cosas de la forma perfecta la primera vez; esa no es la realidad del código de escritura. Cometemos errores y los señalamos y arreglarlos a tu entorno. Haciendo esto, desarrollamos la habilidad en el uso de herramientas y técnicas de depuración. Al momento de terminar el curso habrás trasladado en la imagen y examinando los errores de la lógica y de syntax tan mucho, que será la segunda naturaleza para ti cuando trabajas. Ambiente neto. Esto pondrá tus nuevas habilidades aprendidas en un uso práctico y impresionará a tu jefe y trabajador.

El curso está completo con archivos de trabajo que alojados en GitHub, con la inclusión de algunos archivos para que te resulte más fácil de replicar el código que se está demostrado. Podrás trabajar con el autor mientras trabajas en cada clase y recibirás un certificado verificable de culminación al finalizar el curso.

Conoce a tu profesor(a)

Teacher Profile Image

Trevoir Williams

Jamaican Software Engineer

Profesor(a)

Habilidades relacionadas

Diseño Más de diseño Arquitectura
Level: Intermediate

Valoración de la clase

¿Se cumplieron las expectativas?
    ¡Superadas!
  • 0%
  • Sí
  • 0%
  • Un poco
  • 0%
  • No realmente
  • 0%

¿Por qué unirse a Skillshare?

Mira las galardonadas Skillshare Originals

Cada clase tiene lecciones cortas y proyectos prácticos

Tu membresía apoya a los profesores de Skillshare

Aprende desde cualquier lugar

Ve clases sobre la marcha con la aplicación de Skillshare. Progresa en línea o descarga las clases para verlas en el avión, el metro o donde sea que aprendas mejor.

Transcripciones

1. Introducción: Hey chicos, bienvenidos a mi nuevo curso, ASP.Net core, arquitectura sólida y limpia. Soy tu instructor, Travolta Williams. Tengo más de 10 años de experiencia como ingeniero de software y conferencista. En este curso, vamos a estar viendo bastantes cosas. Vamos a ver implementar principios sólidos y arquitectura limpia en una aplicación ASP.Net Core. En el camino, vamos a trabajar con herramientas avanzadas como mediador o bottom-up o Fluent API para la validación, estaremos construyendo Global Exception Handling y logging. Estaré mirando el patrón C QRS, que es un patrón maravilloso que mantiene nuestro código segregado y en tamaño de bit es para máxima integración y extensibilidad. Al finalizar este curso, vamos a entender cómo hacer pruebas unitarias, cómo integrar servicios de terceros en una aplicación y ver cómo podemos implementarlo con fines de producción. Si bien, los requisitos para este curso incluyen Visual Studio 2019 y dotnet five, o la última versión. En el momento en que estás haciendo este curso, todo lo que vamos a estar haciendo es a prueba de futuro y estos principios se pueden transferir a las últimas versiones sin ningún problema. Para sacar el máximo provecho de este curso, sí te recomiendo que tengas cierta cantidad de conocimientos de programación C Sharp y dotnet así como conocimiento de desarrollo de bases de datos. De cualquier manera, haré que el contenido sea muy amigable para principiantes y no debes tener absolutamente ningún problema en seguir y saber que tienes toda la información que necesitas. Te veré pronto en el curso. 2. Comprender la arquitectura limpia: Muy bien, así que hemos mirado los principios que rigen la arquitectura limpia de las aplicaciones. Ahora veamos a qué nos referimos exactamente por arquitectura limpia. Porque la arquitectura limpia no significa necesariamente un buen software. Bueno es muy relativo a quien lo está viendo. Por ejemplo, si se le encomendó desarrollar un sistema de gestión de leads para el departamento de RRHH y lo hiciste, y RHH está contento, entonces es un buen software. No obstante, si no lo hiciste siguiendo estos principios, entonces podría verse como software malo, pero las prácticas brotan el desarrollo de software en general, por tu equipo o quien sea tu sucesor cuando están tratando de mantener esta aplicación. Por lo que la arquitectura limpia no es necesariamente directamente proporcional al buen software. Depende de quién sea el receptor fuera y en qué momento. Entonces vamos a discutir todo lo que entra en desarrollo de software y los diferentes tipos de arquitectura para que podamos apreciar plenamente cuándo necesitaríamos intensificar un poco más nuestras consideraciones de diseño y cuáles son los pros y los contras de esto son. Por lo que la primera que vamos a querer mirar sería todo en una sola arquitectura. Y lo haré todo en una sola arquitectura, es más fácil de entregar. Puede ser estable y verse como una solución a largo plazo. Todo en uno arquitectura podría ser fácilmente cuando nos scufled a estrenar es ser dotnet aplicación Core. O si esta es la primera vez que haces ASP.Net Core, probablemente estés más familiarizado con Ruby on Rails o larva o jungla. Una vez que tengas ese diseño general del proyecto, eso podría verse fácilmente como una arquitectura todo en uno. Tienes todas las carpetas y todo lo que tienes que hacer es crear tus archivos, crear tu completo hace esa separación de preocupaciones ahí mismo y todo está bien, el software funcionará. No obstante, definitivamente es difícil hacer cumplir principios sólidos. Cuanto más tengas que empacar en esto todo en una arquitectura es más olores de código y malas prácticas que podrían tener que verse comprometidas. Está bien, así a medida que crece, se vuelve más difícil de mantener y su testabilidad. Y cuando nos sentamos esta estabilidad, nos referimos como con la depuración y por pruebas unitarias de extensión, la capacidad de probar dos unidades de esto todo en una sola arquitectura. Esa capacidad disminuye a medida que los roles de aplicación. A continuación, queremos ver la arquitectura en capas. Y toda arquitectura estratificada es un paso por encima de todo en uno donde en lugar de separar nuestros módulos o nuestros trozos de código y archivos, lo siento, por carpetas, empezamos a buscar crear proyectos y hacer referencia a estos proyectos. Por lo que en ESP dotnet Core y en sus obligaciones en general, puedes desarrollar bibliotecas de clases donde pongas todas tus clases y solo haces referencia a ellas como necesites. Y luego terminarías con diferentes capas. Tienes una capa que se ocupa de las cosas de la interfaz de usuario. Tienes una capa que necesita con la lógica empresarial. Y tienes una capa que grava la inflamación entre base de datos y la lógica empresarial hasta. Y luego terminas con una estratificada nuestra aplicación. Ahora, es más fácil, definitivamente imponer principios sólidos y es más fácil minton bases de código más grandes. No obstante, esto todavía accede a una aplicación debido a que todas estas capas siguen siendo algo dependientes entre sí. Por lo que todavía no estamos aprovechando plenamente todo el principio de inversión de dependencia, así como todo el principio de acoplamiento suelto. Y ahora por fin, estamos viendo The only on architecture que se enseña en gran medida como arquitectura limpia. Ahora cuando hablamos solo de arquitectura, estamos hablando de diferentes formas de ver capas. Y en esta etapa, queremos apoyar cualquier tipo de aplicación. Quieres tener todo muy modular para que podamos poner en un nuevo módulo sin interrumpir el resto de la base de código. Podemos tomar auto módulo y podemos hacer cambios y probar más fácilmente sin interrumpir las partes existentes de la aplicación. Entonces cuando hablamos de la arquitectura Odeon, estamos hablando de tal vez tener alguna aplicación cliente para la interfaz de usuario. Esta podría ser una aplicación Web ASP.Net. Esta podría ser una aplicación móvil. Estamos hablando de que ambos tengan servicios API que se sentarán encima de la obligación en el núcleo. Y estos servicios API, una vez más, serían de código abierto. Realmente no le importa lo que sea el cliente y los riesgos es lo que estaremos usando. Pero no le importa si es un cliente móvil, no le importa si es un cliente web, un cliente blazer, y enojar a un cliente, Es solo taxiar datos de la base de datos a quien esté escuchando. Y Buck, No, las pruebas se vuelven mucho más fáciles de hacer porque podemos probar las diferentes capas de forma independiente y luego podemos probar cómo interactúan las capas entre sí. Entonces si se introduce algo para romper alguna de estas interacciones existentes, entonces podemos detectarla con mayor facilidad. Y desde temprano nulo para la infraestructura estamos hablando del módulo. Entonces estamos hablando de registrar el acceso a datos. Si tenemos más de una base de datos con la que tenemos que estar tratando, deberíamos poder poner en una capa completamente nueva para hablar para deshacer base de datos sin interrumpir nada que la arquitectura existente estaba haciendo con la antigua base de datos. Podemos poner en registro, podemos poner en mapeo, validaciones. Todo puede entrar y nuestra cómoda sin interrumpir nuestra aplicación. Entonces contras, sin embargo, hay una curva de aprendizaje porque se necesita saber qué fue raro y hay diferentes interpretaciones de este tipo de arquitectura. Por lo que puede que veas diferentes sabores. Si lees dos o tres fuentes diferentes, vas a ver dos o tres implementaciones diferentes de su enemigo. Me pregunto cuál es el que debería usar? Por supuesto, el contexto determina mucho de lo que tú y otros desarrolladores hacen, las decisiones que tomas en tu arquitectura. Y así, ya sabes, solo tienes que usar eso, solo obtén el conocimiento y usa tu contexto como tu guía y otra estafa a este tipo de arquitecturas que puede ser muy tiempo porque hay mucha su lote más archivos que estarán involucrados cuando podríamos hacer algo con dos archivos ahora probablemente requerirá cinco. No obstante, una vez más, los beneficios serían que tengamos alfombras sueltas y más testabilidad. Entonces con todo eso dicho, ten cuidado. No todas las aplicaciones necesitan, comillas, arquitectura limpia. buen software satisface las necesidades del negocio y el software mantenible aumenta la vida útil del software. Por lo que hay que encontrar un equilibrio en todo momento. No veas que cada proyecto que tienes que hacer va a necesitar una arquitectura limpia, empieza pequeño y se extiende según sea necesario. 3. Qué vamos a construir: Bienvenido de nuevo. En este video, estaremos echando un vistazo a la aplicación que queremos construir o reconstruir. Por lo que en mi pantalla tengo un sistema de gestión de leads que se construyó con una velocidad en él core 3.1. Y se ven todas las cosas que se implementaron dentro de esta solución. Ahora, se ve bien y hace lo que fue diseñado para hacer. Entregó capacidades de gestión de licencias al departamento de RRHH. Puedes encontrar el código fuente para esta aplicación en mi cuenta de GitHub y puedes buscar el repositorio leave dash management, dash dotnet core. De hecho, esta es la aplicación que se construyó en mi curso, completa ASP.Net Core y Entity Framework Development. ¿ Por qué fue perfecto para principiantes? Es cierto con muchos olores de código y formas ineficientes de escribir el código que un principiante puede retomar. Pero luego a medida que te pongas más intermedio a avanzado, empezarás a darte cuenta de que son mejores maneras de hacer estas cosas. Y eso es exactamente lo que estaremos discutiendo en este curso. Ahora, sólo tomaré y miraré la estructura del proyecto. Y una vez más, es completamente opcional descargarlo. Simplemente puedes seguir adelante, pero te estaré mostrando algunos de los puntos débiles de la arquitectura y algunas de las decisiones que se tomaron durante el desarrollo de esta aplicación. Uno, verás que esto sólo tiene un proyecto. Ahora si recuerdas antes cuando miramos los diferentes tipos de arquitecturas de proyectos, esto caería justo en eso todo en una sola arquitectura dondequiera que la cosa esté solo en un proyecto, de fácil acceso. Entonces una vez más, para principiante, eso está bien porque quieres vistas, llegas a las vistas que quieres que vaya a datos. Es toda su separación de preocupaciones en este punto está limitada y restringida a solo carpetas. No obstante, en el panorama más amplio, y cuando se quiere agregar más cosas, este proyecto puede engordarse muy a medida que se intenta extenderlo, por lo que será bueno sacarlo. Otra cosa que huele nuestro código que quisiéramos abordar es la repetición de código. Por lo que incluso en la construcción de nuestros modelos de datos, verías que tipo de repetimos algunas de las propiedades. Tenemos ID ahí, tenemos ID aquí otra vez, esas pequeñas cosas en algunos de los controladores, repetimos código cuando no necesariamente lo necesitamos. Y luego mientras estamos en el tema de los controladores, hay lo que llamaremos controladores de grasa aquí. Entonces estamos haciendo mucha lógica empresarial, mucho procesamiento aquí mismo en el controlador, que lo hace muy pesado. Por lo que quieres un poco obstruir esos procesos de lógica empresarial lejos de tus controladores. Ahora, fuera de las razones de desarrollo para rediseñar y rediseñar esta aplicación desde una perspectiva empresarial o empresarial, una, RHH quiere extender esta aplicación de la forma en que se construye, ¿verdad? No, es bastante difícil hacer eso sin alterar el código existente. Eso es 1, 2, no es muy comprobable en su estado actual. Entonces aunque intentemos extenderlo, vamos a tener más own off testing porque tenemos que hacer más pruebas de regresión y pruebas manuales sobre eso. Y luego tres, cuando lo hacemos en una onda de arquitectura limpia, realidad tenemos la opción de extenderla a diferentes tipos de aplicaciones cliente y potencialmente implementadas como software como servicio donde la API está llevando a cabo todo el lógica empresarial e interacción con la base de datos y la aplicación cliente es completamente anónima que teníamos. Esta aplicación cliente podría haber sido una aplicación MVC, podría haber sido una aplicación blazer, podría haber sido una aplicación móvil. Por lo que esa es una de las razones de la propuesta de valor por las que se puede implementar clave y arquitectura. Entonces volviendo a lo que dijimos antes, buen software es el software que hace su trabajo, ¿verdad? No, este es un buen software. El departamento de RHH está tranquilo, contento con él y cómo lo hace, qué tiene que hacer. No obstante, cuando empiezan a pedir más cosas, nos damos cuenta en nuestro dicho técnico que se vuelve un poco más difícil extenderlo, modificarlo, probarlo. Entonces donde lo estamos protegiendo para que aún podamos entregar toda la funcionalidad que el departamento de RRHH quiere al mismo tiempo que conservamos la capacidad de mantenerla de una manera muy eficiente. En nuestra siguiente lección, comenzaremos a configurar la solución para nuestra nueva arquitectura. 4. Configuración de la solución: Bienvenido de nuevo. En nuestra primera lección práctica, vamos a estar configurando nuestra solución. Por lo que tengo Visual Studio 2019 abierto. Si no tienes Visual Studio 2019 ya instalado, puedes ir fácilmente a Visual Studio dot Microsoft.com slash VS y descargar la edición de la comunidad. El Community Edition es gratuito para uso educativo e individual. Por supuesto, si lo eres, si eres un comercial de lo que se espera conseguir la versión profesional o la de empresa. Una vez que lo hayas descargado, se te presentará un instalador. Y lo que realmente necesitas de este instalador, al menos es la carga de trabajo de ASP.Net y desarrollo web. Por lo que al marcarlo, estás indicando que quieres ese trabajo a través de él. Verás todas las cargas de trabajo disponibles. Puedes llevarlos si así lo deseas. Por supuesto, cuanto más tomes es más necesitas descargar. Pero para este curso realmente solo necesitas este que te dará todas las herramientas necesarias para cualquier aplicación Web ASP.Net así como dotnet cinco. Entonces una vez que hayas completado esa configuración o si ya tenías instalada y continúa conmigo. Y vamos a ir a crear un nuevo proyecto. Entonces lo que vamos a hacer es crear una solución en blanco. Tengo en mis plantillas de proyecto recientes. Pero si lo haces por encima de eso, siempre puedes buscar solución en blanco en esta área y luego obtendrás una solución vacía que no contenga proyectos. Entonces eso es lo que queremos y vamos a estar llamando este proyecto H son puntos dejar gestión. Ahora no hay razón en particular para que yo lo llame así. Se trata de una aplicación de gestión de leads que se está construyendo para el departamento de RRHH. Si se estaba construyendo para una empresa, entonces probablemente querrías decir empresa punto el tipo de sistema. Entonces si quieres, puedes seguir adelante y usar mi nombre o cambiar ese nombre en consecuencia. Pero una vez que hayas puesto un nombre que sea válido, entonces puedes seguir adelante y hacer clic en Crear. Ahora no estaremos escribiendo ningún código en esta lección, pero estaremos sacando esa estructura del proyecto como la necesitamos durante la duración de este curso o de todo este proyecto. Entonces lo primero que voy a hacer es agregar una carpeta y voy a llamar a ésta SRC, abreviatura de fuente, y otra carpeta a la que vamos a llamar pruebas. Ahora bajo SRC, voy a agregar algunas carpetas más. Voy a llamar a ésta la API, porque eso es lo que interactuará con nuestra aplicación cliente. Voy a tener otro llamado core, uno más llamado infra structure, y finalmente, uno para la UI. Entonces eso es todo lo que estamos haciendo para esta lección. Simplemente estamos configurando la estructura del proyecto. Entonces, cuando regresemos, comenzaremos a crear los diferentes proyectos que irán en cada una de estas secciones. 5. Crear el proyecto de dominio: Muy bien chicos, bienvenidos de nuevo. En esta lección, estaremos creando nuestros proyectos de dominio. Por lo que nuestros proyectos de dominio irán por debajo de nuestra carpeta central dentro de nuestra aplicación, podemos seguir adelante y agregar un nuevo proyecto. Y lo que vamos a estar haciendo es agregarlo como biblioteca de clases, biblioteca C-sharp Docx de tipo dotnet estándar. Está bien, así que no está en estribor permite compartir código a través de muchas plataformas diferentes. Por lo que sólo usaremos esa para todas nuestras bibliotecas de clase. Y lo estamos llamando HR dot leave management domain ya que se utilizará para almacenar todos nuestros objetos de dominio o clases de entidad que se traduzcan a nuestras tablas de base de datos. Para que pueda seguir adelante y golpear Next. Y el marco objetivo aquí es el estándar 2.1 de dotnet. Adelante y golpea Crear. Ahora una vez hecho eso, obtenemos nuestra clase predeterminada uno, que en realidad podemos eliminar y luego empezar a poblar con nuestras clases. Entonces, volviendo a nuestro proyecto en GitHub, simplemente rápidamente, verías que las clases de dominio se llevaban dentro del proyecto en una carpeta llamada data. Por lo que nuestras clases de dominio incluyeron asignación de licencias, solicitudes de licencia, y tipo de licencia. Si quieres, puedes seguir adelante y recuperarlos, pero voy a estar pasando por ellos de todos modos. Entonces si solo echaras un vistazo rápido a estas clases, verías que cada una tenía una identificación, y también teníamos un montón de propiedades en cada una. Entonces cuando propiedades ese tipo de repetido incluiría fecha creada entre el tipo de hoja y el registro de asignación de hojas. Y entonces es inconsistente porque la gestión de la licencia o lo siento, las solicitudes de licencia realmente no tienen eso. Entonces estaremos arreglando algunas de esas inconsistencias, además de reducir las repeticiones entre ellas. Entonces voy a empezar con tipos de hojas. Por lo que sólo voy a ir al proyecto click Agregar nueva clase. Lo estamos llamando tipo hoja. Y voy a hacer este foro público No, dentro de tipo hoja, lo que vamos a tener nuestros campos para ID, nombre, Días predeterminados, y cada uno creó. Ahora sí especificé ese campo de fecha, como fecha creada es realmente un campo de auditoría y esto necesita ser teléfono a través de las diferentes clases. Entonces solo voy a seguir adelante y agregar todas las clases de entidad para que puedas pausar, replicar eso. Para la solicitud de licencia, vamos a tener un campo ID, inicio y fechas de fin, tipo de hoja. El dato solicitado, solicita, comentarios, fecha, axón, y aprobado en forma de booleano nullable, y cancelado en forma de booleano. Para que puedas seguir adelante y replicar eso. No, si estás comparando esto con lo que está en la referencia de GitHub, faltan algunos campos, para los cuales no estamos del todo listos todavía en forma del empleado, que serían algunos datos relacionados con el usuario. Todavía no tenemos eso, así que no estamos priorizando que podamos introducir eso más adelante a través de algunas migraciones. Conoce la tercera entidad que vamos a sumar es asignación de licencias. Y para éste vamos a tener el DNI, el número de días, la fecha creada, tipo de licencia, ID tipo hoja, y punto. Una vez más, como que he omitido los campos relacionados con los empleados también. Esas anotaciones de datos. Ahora en cuanto a repetir campos versus la necesidad de tener consistencia con al menos la visa hay que repetir, a saber, la fecha creada. Por lo general cuando hablamos de auditoría, queremos tener fecha creada, quién la creó, la fecha modificada, y quién la modificó por última vez, ¿verdad? Para que así podamos hacer un seguimiento de todo lo que sucede a través de él como casi todos follaron. En realidad resolveríamos algunas de las cosas con todo el referenciar al empleado y así sucesivamente con estos sentir auditoria. Entonces lo que voy a hacer es introducir otra carpeta en este proyecto de dominio. Y voy a llamar a esta carpeta común. Y luego dentro de común, tendré una clase a la que voy a llamar a esta entidad de dominio. Nadie sabe que mi entidad de dominio base tiene, bueno, es bueno tener todos los campos base que conozco cada clase o cada entidad de dominio va a necesitar. Voy a hacer de esto una clase abstracta para que no pueda ser instanciada por sí sola. No obstante, puede ser heredado por todos los demás. Entonces esto va a ser ID porque cada mesa va a necesitar una identificación. También voy a tener para otros campos, uno para la fecha creada, luego creado para entonces una fecha y hora para los datos Last-Modificado y otro para el último modificado por. Ahora con esta entidad de dominio base, puedo saber que todos los demás hereda. Simplemente puedo volver a mi clase de entidad real y dejarla heredar de la entidad de dominio base, incluyendo cualquier referencia que falte usando punto de control. Y ahí se ve que estos campos que tengo INSEAD dejan asignación que tienen los mismos nombres que los de basados en una entidad se están iluminando. Entonces eso significa que no necesito repetirlas. Está bien. Eso se ve un poco más limpio. Está bien, Así que voy y dejo solicitudes de lo que hago lo mismo. Adelante y heredar incluir las referencias faltantes y luego de repente no necesito ver identificación por aquí tampoco. Y luego en tipo de hoja, hago justo lo mismo, incluyendo referencias faltantes. Y luego puedo quitar todos los campos repetidos. Por lo que se basan en una entidad nos da acceso a ciertos campos que se espera que se repitan en toda entidad ya que todos queremos que tengan estos. Está bien. Entonces con todos esos cambios realizados, sigamos adelante y golpeemos Control Shift y B para hacer una compilación y tenemos una compilación exitosa. Para que podamos pasar a la siguiente tarea. 6. Crear el proyecto de aplicación: Oigan chicos, bienvenidos de nuevo. En esta lección estaremos discutiendo nuestra capa de núcleo de aplicación. Ahora el propósito de esta capa es sentarse entre nuestra aplicación, siendo la aplicación lo que sería querer acceder a la base de datos y a la base de datos. Por lo que en esta capa se estarán definiendo todos esos parámetros de acceso para mediar entre la aplicación que llama y la propia base de datos. Por lo que este proyecto se sentará directamente dentro de nuestra carpeta central. Entonces sigamos adelante y agreguemos una nueva biblioteca de clases. Y yo quería estar llamando a este uno puntos de HR, dejar aplicación de punto de gestión. Adelante y agrégalo una vez más, estamos usando dotnet poco menos de 2.1 y seguir adelante y crear. Entonces ahora que tenemos nuestra biblioteca de clases, voy a quitar la clase predeterminada, y luego voy a agregar dos carpetas nuevas a este proyecto. Entonces el primero va a ser persistencia y luego encipher sistemas, vamos a tener otra carpeta llamada contratos. Por lo que dentro de los contratos vamos a estar definiendo todas las obstrucciones para nuestros repositorios. Ahora el jurado está fuera sobre cuáles son las mejores formas de implementar esto. Una vez más, hay unas cuantas opiniones es la arquitectura propuesta, y hay unas cuantas opiniones y algunas opiniones se implementan en base al contexto. Pero sólo voy a explicar por qué estamos usando el patrón de repositorio. Entonces uno, en el, acuerdo con los principios secos, no queremos repetir consultas con demasiada frecuencia. Además, podría tener operaciones especializadas que necesite llevar a cabo en cualquiera de estos objetos de dominio. Entonces cuando definas un repositorio por objeto de dominio, entonces puedes tener cotización personalizada o métodos personalizados dentro de ese repositorio para estos, ¿verdad? No, no estamos implementando el repositorio sin embargo, solo estamos definiendo el contrato. Entonces el contrato aquí, el primero será una interfaz y lo voy a llamar ij repositorio genérico. Dije clase aquí, haciendo una clase. Pero aunque tengas precaución de que solo puedas convertirla en una interfaz pública. Ahora vamos a decirle a esta interfaz que se implementará relación a una clase llamada T. Así que solo estamos usando genéricos en concordancia con el nombre repositorio genérico para que cualquiera de nuestros objetos de dominio pueda ser utilizado para acceder a la funcionalidad relacionada con la base de datos mediante esta interfaz. Por lo que algunos de los métodos que vamos a implementar en esta interfaz incluyen un GetMethod, por lo que tenemos la tarea T. Y entonces solo puedes seguir adelante e incluir cualquier biblioteca que falte. También vamos a tener tarea, conseguir todo lo que este está regresando. Solo leo listas, sabe si es la primera vez que ves este tipo de datos. Por lo general, y personalmente suelo usar una lista o un nihilista o uno de esos tipos de datos de Colección más populares que leo en una lista. Ese es beneficio es que lo mantiene en un estado de solo lectura por lo que no se puede modificar una vez que se ha extraído de los mesones de datos enviados. Por lo que menos camiones y menos operaciones relacionadas con la base de datos después del pool de datos. Entonces lo veremos en unos pocos, pero ese es el tipo de datos que estoy usando. Una vez más, podrías haber usado fácilmente cualquier otro tipo de colección de tipo T. Pudo haber sido una lista, podría haber sido una colección. Pero entonces leí en la lista está sirviendo el propósito que quería. Vamos a tener la tarea de agregar en donde también Linda tiene tareas que actualizar y eliminar. Entonces se ve que los repositorios genéricos no sólo genéricos para t, sino que también es un genérico en cuanto a la funcionalidad proporciona cuáles son las funciones crud básicas y estándar. También hay una convención de nomenclatura donde la gente pondría la palabra async porque se puede ver donde todos usando tareas aquí. Por lo que algunas veces verías luego definirla como un fregadero. Entonces es obvio que esta va a ser una función asíncrona. Por lo que no podías seguir esa convención de nombres si quieres. No voy a hacerlo, así que podemos seguir adelante. Ahora lo que pasa con el repositorio genérico es que una vez más, son solo las funciones crud genéricas que cada tabla de base de datos puede necesitar realizar alguna vez. No obstante, cuando tienes algo específico para dejar operación de asignación o una operación de solicitud de licencia, no puedes construir la sal y el código podría ponerse missy si intentas construirlo en ciertas partes de la aplicación. Entonces lo que vamos a hacer es en comentarios repositorios específicos basados en nuestro repositorio genérico o ampliar nuestra funcionalidad genérica, pero específica para cualquiera de nuestros objetos de dominio. Entonces solo voy a volver a los contratos y voy a añadir un nuevo ítem en forma de clase una vez más, pero realmente va a ser una interfaz y lo voy a llamar, dejo repositorio de solicitud. Una vez que eso se crea, lo convertimos en una interfaz pública. Y luego le hago saber que se está extendiendo repositorio genérico y es específico de nuestro tipo de clase de solicitud de licencia. De acuerdo, así que dejar solicitud es nuestro dominio. Recuerda que esto era relativo al tipo t Entonces esta es la T que estamos pasando, pero entonces verás aquí que no sabe nada de decir 70. Por lo que necesitamos agregar referencia al dominio de gestión de recursos humanos. Entonces puedes ver que con toda honestidad, eso no me ha funcionado del todo cuando uso su lado, solo pasa a dependencias. Déjame hacer eso otra vez, lo siento, dependencias en proyecto o de un amigo. Y luego solo tomo la referencia a los objetos de dominio. Haga clic en Aceptar. Y entonces puedo saber, incluir que usando declaración aquí. Muy bien, entonces dentro de este repositorio, entonces si tenemos funciones especializadas relativas a solo dejar solicitudes, entonces podemos definirlas aquí con el modelado del repositorio genérico y sin los otros repositorios específicos necesitando verlo, queremos mantener todo tipo de contenido en un solo lugar. lo que siguiendo este ejemplo, sólo voy a seguir adelante y defender a los demás repositorios. Dejo asignación y dejaré repositorios de tipo. Por lo que una vez que se realiza esa actividad, terminamos con otras dos interfaces. Por lo que tenemos nuestro repositorio genérico. Tenemos o dejo repositorio de asignación, que está implementando o heredando u otro repositorio yo genérico relativo a dejar asignación. Y luego tenemos eso de nuevo para tipo de hoja con dejo tipo repositorio extendiendo genérico relativo a tipo de dejar. Entonces eso es realmente todo para esta lección donde están sentando los contratos. Y esos contratos están en los foros de estas interfaces. Porque recuerda que no queremos interrumpir directamente con el código cuando estamos llamando a lo que vamos a estar tratando con abstracciones de esa manera podemos hacer cambios de código sin interrumpir demasiado la cotización del cliente- aplicación lateral. 7. Implementar la Automapper: Oigan chicos, bienvenidos de nuevo. En esta lección vamos a estar sentados auto mapeador. Sepa si no sabe qué es la parte superior de otoño, eso no es problema. En realidad es solo una biblioteca que nos ayuda a convertir entre un tipo de datos a otro. Más simple, ¿verdad? Entonces el contexto detrás de por qué será útil es que estaremos implementando el patrón mediador en un siguiente video. Pero eso mediates o patrón estará actuando como un mecanismo de mensajería entre lo que viene de la planta y lo que necesita ir a la base de datos. Es, en términos generales, mala práctica interactuar directamente con los objetos de dominio, al menos antes de llegar al repositorio. Eso significa que no deberíamos estar permitiendo que ninguna aplicación de llamada y el cliente, cualquier aplicación que esté hablando con nuestra aplicación en núcleo nos esté enviando directamente o directamente objetos fuera del tipo de objeto de dominio. En cambio, creamos obstrucción. Por lo que creamos objetos de transferencia de datos o modelos de visualización. Puedes llamarlos cualquiera de ellos, pero en realidad son solo cruces ese tipo de aspecto del objeto de dominio, pero tienen restricciones basadas en la operación. Por lo que editar operación tiene diferentes requisitos de tal vez una operación de creación. Y así presentarías el id 1 y el id no se presentaría en el otro. Una vez más, todo lo que tienes son obstrucciones para eso. Se puede obtener granular o se puede mantener general. Eso depende de ti. El punto es alter mapper ayudará con la conversión entre la obstruida o amigable con el cliente de este objeto y la versión amigable con la base de datos de este objeto. Esto va a promover el acoplamiento suelto a lo largo de nuestra aplicación. Entonces con todo eso dicho, la configuración no va a ser muy complicada para ésta, lo que voy a hacer dentro de este proyecto de aplicación es crear una nueva carpeta y sólo vamos a llamarla perfiles aunque. El perfil es básicamente solo un archivo de configuración para túnel automotriz que se permite convertir entre un tipo de datos a otro. Entonces voy a crear un vestido nuevo dentro de esta carpeta. Y lo voy a llamar perfil de mapeo. Y luego necesito presentarme y voy a hacer esto público por supuesto, pero necesito ir a NuGet y conseguir nuestro altar Biblioteca Mapper. Entonces solo voy a hacer clic con el botón derecho en dinero. ¿ Se puede conseguir biblioteca? Y luego voy a buscar autor definitivo. Y la que me interesa es la última de las extensiones Bardot para inyección de dependencia. Vendremos con todas las dependencias incluyendo la biblioteca de PR definitiva base y cualquier otra cosa necesaria para que pueda usarse para inyección de dependencia en consecuencia. Entonces solo voy a seguir adelante e instalar esa. Por supuesto, aceptar y permitir cualquier problema que surja una vez que esté instalado. En lugar de mapear perfil, voy a dejar que herede de una clase llamada perfil. Y esta clase es llamada en auto Mapper Library. De acuerdo, entonces tenemos la configuración del perfil. Eso es bueno. Bueno lo siguiente que voy a definir serían mis objetos de transferencia de datos. Por lo que he creado una nueva carpeta dentro de este proyecto de aplicación. Y en esta carpeta tengo algunos archivos. Uno, tengo un archivo o carpeta común otro con un archivo común llamado detalle base. Tan similar al acarreo y estamos sentados a bordo de objetos de dominio, tenemos un común y luego donde la entidad de dominio base, que tenía algunas propiedades base que deberían estar a través de todos estos objetos de dominio. Es de la misma manera que acabo de hacer detalle basado. Y la propiedad común sería ID. No necesito la fecha creada y demás con los DTL, eso es solo para auditar, así que eso está en segundo plano. Entonces lo que realmente necesito compartir entre todos ellos sería la identificación. Y luego dentro de cada uno de estos, que aún no he hecho esos, entonces tendré otras propiedades que sé que cada uno de ellos necesita tener para poder taxi con éxito información útil para mí. Por lo que esta parte es tan fácil como ir a dejar tipo y tomar las propiedades que conoces, querrías permitir que tu aplicación o tus usuarios puedan interrumpirla. Por lo que eso dejaría peticiones. Estas son todas propiedades requeridas. Yo solo estoy literalmente, como ves, solo estoy copiando y pegando la parte dura realmente fue solo definir el detalle base y dejar que la herencia se pusiera en esas identificaciones y no detalles, hablar con detalles. Entonces ven aquí que el tipo de hoja se está reteniendo. Se ve que el tipo de hoja se está reteniendo. No dejas que el DTO sepa sobre el dominio. Muy bien, así que esto debería ser de tipo hoja DTO, y esto también debería creer que DTO, y como regla general, detalla velocidades y DTL. Otoño superior saber es lo que permitirá la conversión entre uno o el DTO y el dominio. Entonces en lugar de mapear perfil, vamos a tener un constructor. Por lo que solo puedes ahorrar bañera CTO, tina que genera nuestro constructor. Y luego voy a tener una línea que diga Crear mapa. Y crear podría estar diciendo entre una fuente y un destino. Entonces T fuente sería, digamos que la solicitud de licencia sería mi fuente. Ese es el objeto de dominio. Leave request, DTO, y ese sería mi objeto de transferencia de datos. Muy bien, entonces estamos creando una configuración de mapeo entre la solicitud de licencia y la solicitud DTO y solo cerramos con los paréntesis. Y entonces puedo extender esto de nuevo y decirle que puede revertir MOP. Y último PR es variable para he visto aplicaciones donde la gente pone alguna cantidad de lógica de negocios en otoño arriba mismo cuando se trabaja con aplicaciones complejas y probablemente cruzadas de dominios, probablemente quieras un dominio o un detalle para poder convertir a un dominio objetos en un conjunto y un objeto de dominio en otro. Por lo que en realidad podría tener múltiples configuraciones de mapeo de un objeto a otro. También podrías crear convertidores personalizados para ver este miembro entra directamente en ese miembro coincidente del otro lado, hay una serie de cosas que puedes hacer con eso. Ese podría ser todo un curso por sí mismo. Pero hoy solo lo mantendremos sencillo con nuestros sencillos requisitos de configuración. Por lo que tenemos dejar una ubicación y luego tenemos el DTO coincidente. Y luego finalmente tenemos tipo de hoja. Ahora quiero señalar algo para realmente aludido a ello antes, pero quiero volver a mencionarlo. Hay momentos en los que se quiere conseguir un poco más granular o tener detalles específicos para un determinado propósito. Entonces echemos un vistazo a las solicitudes de licencia. Deja solicitudes detalle tiene bastantes campos. El propósito de un DTO es limitar el número de campos. Por lo tanto, reducir sobre la publicación y están bajo publicación o proporcionar demasiada información al usuario. Entonces lo que estoy tratando de ver es que en caso de que se quiera ver una solicitud de licencia, entonces todos estos datos se vuelven relevantes. Pero entonces en el caso de que realmente solo necesites enumerarlo o mostrar un listado de todas las solicitudes de licencia. Probablemente no necesites todos estos datos que el usuario no necesita ver todos estos datos cuando están solicitando sólo la lista. Definitivamente no necesitarán ver los comentarios en ese punto. Probablemente no necesiten ver la fecha de acción aprobada o cancelada cuando están publicando. Entonces en ese caso, lo que tiende a suceder es que probablemente quieras romperlo un poco más. Por lo que a veces terminarías con una carpeta dentro de los detalles. Y esa carpeta sería específica para tal vez dejar solicitud. Y luego dentro de las solicitudes de licencia, tienes todos los detalles que difieren. Correcto. Entonces sí, deja solicitud detalle. Eso está bien. Este sería por los detalles qué bien, tal vez tengo otros detalles específicos para listar. Por lo que tendrías solicitudes lista D2, que sí, tendría el BSD TO también. Pero entonces tiene muchas menos propiedades en ella. Por lo que probablemente solo necesites hoja tipo la fecha que se solicitó y si no ha sido aprobada o no. Está bien. Entonces, una vez más, todo esto es relativo a lo que creas que necesitas proporcionar. Pero solo estoy viendo que en esta situación, probablemente no quieras poner cada cosa en un solo detalle y luego usar siempre este detalle cada vez que se haga una solicitud, no importa cuán minúscula sea su solicitud o cómo pocos datos que realmente necesitan en esa situación. Por lo que ese es el propósito de la DTO. Entonces en realidad con esos cambios, no lo sé, rompí algún código. Vamos en primer lugar, permítanme actualizar el espacio de nombres en esta licencia solicita detalle. Entonces eso es todo sabe que es nueva ubicación y luego tengo actualizar mi mapeo para saber que tiene solicitudes de licencia, lista, DTO, arrancó un barco también. Así que solo adelante y actualízate esos. Y luego hagamos una compilación o construyo un exitoso. Lo último que vamos a hacer aquí es configurar en el método de registro de cobranza de servicios de AI. Entonces el propósito de esto es, bueno, de acuerdo con la inyección de dependencia, queremos poder tener todos nuestros componentes, todos nuestros componentes inyectables definidos en lugar del nivel de aplicación. Pero entonces cualquier aplicación cliente puede seguir adelante y simplemente llamar al método y tenerlo registrado dentro de sí mismo. Cuando lleguemos ahí, lo verás, pero yo sólo haré esto bien? Y también esto serían aplicaciones, servicios, registro. Entonces esta va a ser una clase estática pública y va a tener un método al que voy a llamar public static void Configure Application Services, que toma un parámetro de colección de servicios de IA. Por lo que podemos simplemente seguir adelante e incluir cualquier referencia que falte. Y luego dentro de esto llegamos a ver servicios dot add, auto, mapper. O diría que si estás familiarizado con dotnet Core y la inyección de dependencia, verías que esto es solo un servicio llamado acción que habrías visto en el archivo de inicio para cualquier aplicación de dotnet Core. Entonces la cosa es que lo estamos abstrayendo solo a este proyecto para que cuando tengamos esa aplicación dotnet Core, solo podamos llamar a este método. Y entonces seguiría adelante y registraría cada servicio que se define dentro de ese método. Entonces estamos agregando auto mapper y luego voy a decir punto de ensamblado, conseguir ejecutando ensamble. Adelante y agrega cualquier referencia que falte. Ahora si estás familiarizado con la automática o has trabajado con ella antes, pero no necesariamente estás familiarizado con esto. Probablemente estarías más familiarizado con ver algo así como tipo de un entonces encontrarías el perfil de mapeo y entonces eso nos permitiría registrar este perfil tiene la configuración superior de otoño en general. El asunto con esto es que por cada perfil de mapeo que tengas, probablemente tengas que repetir esta línea. Y tú, en función del tamaño de tu aplicación, puedes terminar con múltiples perfiles de mapeo porque he visto donde puedes tener perfiles de mapeo por objeto de dominio y pr, pr detalle de objeto de dominio peering basado en el número de bases de datos son dominios que están presentes, ¿no? Por lo que incluso se encuentra en un nivel de aplicación, una aplicación o una aplicación cliente puede tener diferentes requisitos de Mapping a los de otra para que los mantenga separados. Entonces mi punto es que al decir ensamblado dot get ejecutando ensamblado, simplemente atravesará por cada perfil de mapeo que tenga esa herencia más o menos y solo funcionará. Está bien, no hay forma más fácil de verlo. Entonces así es como estamos registrando nuestro top otoñal en nuestra inyección de dependencia. Y eso es configurar mapeador otoñal en general. Entonces si construimos y es exitoso, entonces volvemos a continuación y continuamos nuestra configuración de aplicaciones. 8. Crea consultas con MediatR: Bienvenidos de vuelta chicos. En esta lección estaremos implementando dos patrones que nos ayudan a promover el acoplamiento suelto a través de nuestra aplicación. Ellos son el patrón mediador y el patrón C QRS. Conocer el patrón mediador se ve como un patrón de comportamiento porque permite definir exactamente cómo interactúan un conjunto de objetos entre sí. En términos más simples, haces una solicitud y obtienes un resultado basado en tu solicitud. Cada vez que realices esta solicitud, puedes esperar este tipo de resultado que es una especie de consistencia que te ayuda a implementar. También te ayuda a obstruir toda esa lógica asociada a esa solicitud desde la aplicación de llamada. Ahora para ver patrón QRS y ver QRS es abreviatura de segregación de responsabilidad de comando y consulta. Te ayuda a separar las operaciones de lectura y escritura de cualquier data store. Entonces en el comando name y query es cualquier cosa que se vaya a aumentar los datos, cualquier operación de escritura, cualquier operación de actualización. Y una consulta soy yo leyendo los datos. Por lo que siempre puedes saber que cuando estás haciendo algo que va a aumentar los datos, es un comando. Si lees en datos es una consulta. Entonces empecemos. Vamos a pasar a nuevo get primero, y vamos a agarrar el paquete mediador, que es interesante, escrito por la misma persona que nos dio a todos el mapeador. Y ese es Jimmy BullGuard. Entonces vamos a seguir adelante e instalar eso. Y una vez hecho eso, vamos a volver a nuestro método Configurar servicios de aplicaciones y vamos a hacer algunos cambios aquí. Por lo que algunos de esos fueron olvidos de mi parte inicialmente, y pido disculpas. Entonces estamos cambiando esto de una voz a un servicio de IA llamado electrón, ese es uno. Y luego estamos sumando estas dos líneas. Estamos viendo servicios dot add mediator, assembly, dot gif ejecutando ensamblado, solo deja que el automapper y estamos devolviendo servicios. Por lo que para el plazo inmediato ADD, sólo vamos a seguir adelante e incluir las referencias faltantes. Y ahí vamos. Entonces así debe ser este método de registro de servicio o cobro de servicios AI. Ahora que hemos hecho esa parte, solo retrocedamos y reunimos nuestros pensamientos y pensables lo que necesitamos hacer, necesitamos implementar los patrones PQRS. Por lo que el CQ son manchas son, y una vez más separa comandos de canteras. En otras palabras, necesitamos carpeta para comandos, necesitamos una carpeta para nuestras consultas. Ya sea Comando o consulta será manejado por lo que llamamos manejador. Entonces cuando haces una solicitud, se maneja y el manejador va a ser ya sea un comando para aumentar los datos o algo para devolver datos. Por lo que ven que hay bastantes partes móviles en este punto. Y es por ello que esto puede tener tantas opiniones sobre cómo se implementa. Entonces, una vez más, no estoy prescribiendo un método de implementación o estructura de carpetas, pero solo te estoy ayudando a visualizarlo. Podrás cambiarlo en función de tus necesidades. Pero esto es todo el mundo se fue a acercar tanto que crea una nueva carpeta dentro de o proyecto de obligación, lo llamo características. Y luego dentro de las características, vamos a tener carpetas por tipo de dominio. Y la razón por la que digo tipo de dominio es que la característica de la aplicación es relativa a lo que vas a estar haciendo contra nuestro objeto de dominio contra las escrituras de éstos, ¿no? Entonces lo voy a estar haciendo en trozos basados la tabla o tablas características específicas que ofrece la aplicación. Entonces empecemos con uno simple como tipos de licencia. Dentro de características vamos a tener tipo de licencia. Voy a darme cuenta de este tipo de hojas. Y luego dentro de la carpeta tipos de hojas, voy a tener algunas otras carpetas. Voy a tener manejadores de solicitudes, luego dentro de los manejadores en cuándo tener comandos y consultas. Y esa es la estructura de carpetas con la que estaré trabajando. Ahora, como dije, opiniones difieren en espera. Podría verse una estructura polar. Algunas implementaciones en realidad tendrían el nivel superior para el maniquí en el nombre de la característica. Y entonces tendrían comandos y consultas. Y luego dentro de comandos o consultas, hay donde tendrían todas las solicitudes o tendrían una carpeta, lo siento, por consulta, digamos dentro de la consulta, tendrían una carpeta para la consulta específica, digamos obtener tipo de hoja lista, esa será la consulta. Por lo que dentro de eso tienes la buena solicitud tipo hoja, obtén tipo de hoja requesthandler y el BTO específico a la misma. Por lo que una vez más, hay muchas maneras en que puede ver esto implementado, pero los conceptos siguen siendo los mismos. Simplemente quieres asegurarte de que puedes identificar comandos de manera diferente a tus consultas y sabes dónde están tus solicitudes. Las solicitudes son relativas a un 100. Entonces ahora que tenemos la estructura de carpetas en su lugar, empecemos con alguna codificación. Por lo que dentro de las solicitudes, la primera solicitud que quiero es obtener la lista tipo hoja. Por lo que nombra sabio convención, siempre se quiere implicar para qué es la solicitud o qué tipo de solicitudes en el neín, ¿verdad? Entonces consigue lista de tipos de licencia y voy a especificar solicitudes. Está bien. Por lo que obtener solicitud de lista tipo hoja. Y esta es una clase pública y va a heredar de las solicitudes de IO. Entonces esto es cortesía de mediador, y luego se va a preguntar, ¿qué debe esperar esta solicitud a cambio? Entonces cuando solicito usar este tipo de datos, ¿qué debo estar recuperando? Bueno, no deberías estar recuperando una hoja de lista tipo DTO, porque una vez más, entrarán los objetos de transferencia de datos R1 y lo que nunca los objetos de dominio. Entonces esas son nuestras peticiones, sin embargo. Podría haber momentos en los que puede tener parámetros que pueden poner en solicitudes y así sucesivamente. Pero éste es uno muy sencillo. No voy a meterme en ninguna de esas complicaciones todavía. Entonces esa es nuestra primera petición. A continuación, necesitamos algo para manejar este tipo de solicitudes. Ahora se trata de una solicitud GET que lo hace de consulta. Entonces dentro de la sección de manejadores, voy a ir a la carpeta de consultas y voy a decir agregar una nueva clase y voy a llamar a este los manejadores de solicitudes. Entonces esa es mi convención de nomenclatura. Entonces tengo una solicitud por un nombre y luego acabo de anexar manejador. Por lo que vamos a seguir adelante y añadir esa como clase pública, que va a heredar una vez más manejador de solicitudes, cortesía de mediador. Y luego solicito manejador dice, Ok, lo que los solicita idealmente ancho, por lo que su solicitud son las solicitudes GET. De acuerdo, así que esa es la convención de nomenclatura que me gusta usar. Y más que eso, ¿ves mucho esa convención de nomenclatura porque entonces específicamente puedes atar nuestra solicitud a un manejador por eso de manera similar, una es la solicitud, otra es el manejador de solicitudes. Para que puedas seguir adelante e incluir cualquier referencia que falte. Entonces dice lo que solicita que mi manejo y qué debo estar esperando regresar. Por lo que el tipo de devolución de la solicitud debe ser el tipo de devolución. Has estado aquí. Por lo que se espera que regrese la licencia tipo DTO. Lo que enumeré fuera de la hoja diabetes. Está bien, así que ahora que eso está hecho, todavía tenemos nuestra línea roja. Esta línea roja es porque necesitamos implementar la interfaz. Por lo que casi automáticamente, en realidad obtenemos un método aquí que dice manejado. Obtiene la solicitud como parámetro. Y entonces aquí es donde escribimos todo el código a manejar cada vez que entra esta solicitud. Ahora antes de empezar a manejar cualquier solicitud aquí tenemos algunas dependencias. Uno, necesitamos poder hablar con la base de datos. Ahora no hemos implementado nada, pero sí tenemos nuestros contratos de persistencia. Por lo que se trata de contratos que en realidad hablarán con la base de datos. Por lo que todavía no estamos interactuando directamente con el dominio aquí en absoluto. Muy bien, así que necesito inyectar las referencias faltantes. Entonces usando S3 o tina, tina, voy a conseguir constructor y luego voy a inyectar y dejo tipo repositorio. Entonces solo voy a seguir adelante y agregar cualquier referencia que falte. Y después haberla escrito en el constructor, puedo saber, decir crear y asignar un campo. Está bien, ahí vamos. Y tiendo a usar el subrayado porque me gusta ver el subrayado. Entonces sé que este definitivamente es el campo privado en la clase, así que esa es mi convención de nomenclatura. No necesariamente tienes causa ves que el código autogenerado no te dio un guión bajo, así que eso está bien. Ahora otra cosa que me gustaría inyectar es yo mapeador, porque sí necesito hacer algún mapeo cuando obtengo los datos de la base de datos, cuando este repositorio devuelve los objetos de dominio, necesito convertirlos a detalles para enviar el buck. Entonces necesito fabricante de automóviles también, así que soy superior, incluir referencias faltantes también ir adelante e inyectado o crea NSA en el campo. Y ahí vamos. Entonces tenemos todo inyectado y listo. Ahora para implementar este código de manejador, lo que voy a hacer es ejecutar una consulta contra el repositorio de tipo hoja. Entonces voy a decir var leaf fetch es igual a 08, dejar la terapia repositorio dot get all. Esto es una espera. Entonces eso significa que este método necesita ser asincrónico. Y luego verás que el único error desaparece al menos. Y entonces lo que necesitamos devolver es la lista de hojas tipo ETL. Entonces voy a decir retorno mapeador de punto mapa. Y entonces aquí es donde esto resulta útil en detalle tipo hoja, pero es una lista de hojas tipo D2 u otra. Y lo que voy a estar mapeando en eso será la lista de objetos de dominio que provienen de la consulta. Y ahí tienes. Todos están contentos. Entonces alguna vez solicito decir quiero las listas tipo hoja, entonces tenemos al manejador diciendo: Ok, puedo manejar esta solicitud por ti. Entonces a eso nos referimos definiendo el comportamiento de la aplicación o definiendo cómo los objetos se relacionan entre sí. Esta solicitud siempre se relacionará con este cazador. Creo que si lo pruebas, múltiples manejadores para las mismas solicitudes, en realidad te encontrarías con errores de tiempo de ejecución debido a alguna ambigüedad. Entonces así es como llegamos a definir claramente que cuando hiciste esta solicitud, siempre puedes esperar el comportamiento. Ahora veamos otra solicitud y aún va a ser una consulta. Pero esta vez quiero una lanza. Tipo de hoja. Entonces estaba diciendo que puede ver solicitudes o puede terminar teniendo campos o propiedades dentro de sus peticiones que serán necesarias para manejar la operación específica. Entonces, ¿qué pasaría si quisiéramos conseguir el tipo elif, no toda la lista, sino el detalle tipo hoja. Entonces voy a crear otra pregunta. Y éste va a ser bueno. Dejar solicitudes de detalle tipo. Una vez más, recuerda hacerlo público. Ahora en esta situación, voy a sumar propiedad y voy a decir id Así que estamos obteniendo el detalle lo que significa que queremos un registro específico. Y la mejor manera de especificar un registro es enviando el DNI. Por lo que necesitamos un manejador para esta solicitud. Entonces voy a agregar ese manejador y la otra clase o obtiene el detalle de tipo solicita 100. Ahí vamos, hazlo público. No, un paso me perdí dentro de las solicitudes que necesitaba heredar de yo solicita. Y sólo está esperando una hoja tipo DTO una esta vez, ¿verdad? Tantas solicitudes DTO, adelante y cumplir con todas las referencias faltantes. Ahí vamos. Entonces el manejador ahora va a heredar de Solicito manejador y seguir adelante y agregar referencias faltantes. Se va a estar manejando solicitudes para buenas Solicitudes de detalle de tipo Leave, y se espera que devuelva tipo ETL. Entonces una vez que todas esas referencias faltantes se hayan ido algo, adelante e implementa la interfaz, y luego empezamos con eso. Ahora vamos a necesitar básicamente las mismas inyecciones que tuvimos que usar. Solo voy a agilizar eso y copiar y pegar ese código y simplemente cambiar el nombre del constructor y seguir adelante y agregar todas las referencias faltantes. Y una vez que hayas hecho todo eso, puedes empezar con el código específico. Entonces en esta situación yo diría que var tipo de licencia es igual a y estamos con la llamada de método. Por lo que deja repositorio dot get y consigue su esperando una identificación. Por lo que tengo el objeto de solicitud aquí dentro del portal manejado métodos. Ahora puedo decir solicitud punto i e. Está bien, otra vez, ¿dónde estamos enseñando? Entonces este espaciado, pero solo te estoy mostrando que así es como seguirías usando esos campos en tu consulta, en tu repositorio genérico o cercano, lo siento. Entonces cuando tienes métodos específicos definidos dentro del repositorio de tipo hoja, entonces puedes tener campos más específicos para tus solicitudes que se necesitan para manejar ese tipo de operaciones. Entonces una vez que logramos eso, lo siguiente que tenemos que hacer es devolver los objetos DTO tipo hoja. Entonces diré mapeador, mapeado en detalle tipo hoja y estamos mapeando el tipo. Entonces una vez más, sólo detalles. Ahora una cosa a tener en cuenta es que en los manejadores que tienen una clara separación entre los comandos y las consultas. Pero en las solicitudes no hay separación clara. Entonces cuando las solicitudes comienzan a crearse para los comandos, tenemos que confiar en nuestros ojos. Tenemos dos OK. No estamos cansados para que no nos confundamos en cuanto a qué petición es el agua. Y no creo que eso sea, es muy eficiente. Entonces voy a tener comandos dentro de mis solicitudes, y también voy a tener consultas. Entonces sé que cada vez que quiero alguna petición, tristeza, e indagaciones, sé exactamente a dónde ir. Y lo mismo para los comandos. Entonces como dije, son estructura de carpetas diferentes. Algunas personas una vez más acabarían de decir tipos de licencia. Y entonces habrían tenido los comandos. Y luego en lugar de los comandos que tendrían los diferentes comandos con todos los recursos necesarios para ese comando específico, el detalle, el manejador, la solicitud, todo en esa sub carpeta. Entonces a medida que rompes este inodoro que vas a necesitar más archivos, más carpetas porque quieres ver una separación clara tanto como sea posible. Una vez más, dijo que esto se implementa es relativo al creador. Entonces solo voy a mover mis consultas que he creado hasta ahora a esa carpeta específica. Y por supuesto, después de actualizar ese espacio de nombres. Y una vez que haga eso, voy a seguir adelante y actualizar mis manejadores para conocer la nueva ubicación de sus solicitudes correspondientes. Entonces con todo eso, amanecer, voy a hacer una construcción y construir fue exitosa y ya ves cómo se está uniendo todo. Entonces si quieres, puedes seguir adelante e implementar las otras características que empezamos con los tipos de hojas. Se puede al menos implementar las diferentes, las dos leídas o las dos operaciones de consulta relativas a asignación de licencia y relativas a solicitud de licencia. 9. Finalización de las consultas para MediatR: Bienvenidos de nuevo chicos que siguen en la misma línea de configurar nuestras consultas para nuestras características adicionales. Por lo que ya pasamos por hacerlo para tipos de hojas. Y la asignación era hacerlo para solicitudes de licencia y asignaciones de licencias. Entonces ya lo he hecho y solo te estaré caminando. Entonces si no lo has completado, iré lo suficientemente despacio y te explicaré todo lo que estoy haciendo para que puedas replicarlo. Y si no, entonces solo podemos comparar notas y siéntete libre de avisarme si has hecho algo diferente a como lo he hecho. Entonces el primero, Empecemos con asignaciones de licencias. Entonces tengo las consultas y tengo el, lo que tengo los manejadores y las solicitudes, y tengo las consultas en cualquiera de ellas. Ahora siguiendo el estándar hasta ahora verías que o las misiones se ven bastante similares a lo que parecían para unos tipos de hojas. Tenemos la solicitud detallada de asignación de licencia de get, que se lleva el DNI. Y también tengo uno para la lista. De acuerdo, así que en la consulta es, tengo una ligera sorpresa para ti. No sé si lo hiciste de esta manera, pero te guiaré por exactamente lo que se ha hecho de manera diferente. Entonces por supuesto estamos incluyendo el hola correcto, El repositorio de asignación de licencias en lugar de opuesto al repositorio tipo hoja porque estamos tratando con ubicaciones de Levi derecha. Ahora en cuanto a nuestro manejo, verías que aquí tengo un método que no pasamos en nuestro, en nuestra configuración de repositorio. Tengo asignación de licencia de get con detalles. Conoce el propósito de mí especificando esto es que cuando obtenemos los detalles de la asignación de hojas y si necesitas un recordatorio o dejar asignación en realidad tiene una propiedad de navegación de tipo hoja, lo que significa si quería show Qué licencia tiene, qué número de b después, mostrar el nombre de ese ícono de la hoja, mostrar el DNI que es inútil, ¿verdad? O el cliente u otro controlan el id, necesitarían alguna cantidad de detalles del tipo de hoja de su lado. Entonces cuando digo con detalles, el propósito de ese método es hacer que incluya esa propiedad de navegación y todo para que para cuando llegue pero que deje asignación, tendría toda esa lógica no están listas y todo lo que tengo que hacer es mapear y regresar. Entonces en este punto solo voy a hacer una pausa y 0 que verías patrón de diseño a veces donde realmente hacen toda esa lógica compleja aquí mismo en el manejador. Entonces he visto donde realmente se conectarían directamente al contexto aquí en el manejador. Y luego hacer todas esas consultas crudas justo aquí en el manejador y luego masajes y luego finalmente devolver lo que necesitan para regresar. Entonces ese es un patrón de diseño que podrías ver. Y el otro es donde abstraemos todas esas lógicas y complejas consultas y lógica empresarial. Y luego mitos para el repositorio. No, no digo que uno sea mejor que el otro porque tuve el enfoque tiene sus pros o contras en cuanto hacer métodos que específicamente se ocupen de un escenario como conseguir la asignación de hojas con los detalles. En términos de eso, podría ser bueno poner eso en nuestro repositorio, un método donde se tiene una referencia directa a dónde ese arte de lógica atrás tipo de operación porque es está sucediendo ese arte de lógica atrás tipo de operación porque esposible que necesite reutilizar ese mismo tipo de lógica en múltiplo manejadores. Por lo que eso en realidad reduciría la repetición del mismo tipo de consultas y del mismo tipo de inclusiones y todo a través de múltiples manejadores. Si solo lo tienes en un solo espacio de repositorio. El inconveniente de los repositorios, sin embargo, es que por lo específicas que pueden llegar las cosas? Sí, tenemos las cosas genéricas, pero obviamente esto no es un comando genérico que cada característica nuestro dominio me objeto, use de la misma manera. Tenemos que tener un método específico y entonces probablemente vamos a terminar por un agujero de conejo de tener muchos métodos específicos en nuestro repositorio. Entonces ese es uno de los sitios don't, el patrón del repositorio sabe, como dije, si haces todo aquí en el manejador, funcionaría. Pero una vez más, los inconvenientes de eso es que podría necesitar repetir ese tipo de operación a través de múltiples manejadores. Y luego terminas repitiendo código en múltiples lugares. Y entonces la modificación podría llegar a ser difícil a largo plazo. Entonces esa es la sorpresa Alpha. Entonces si echan un vistazo a nuestra interfaz, verían aquí que en realidad tiene tanto para la lista como para el individuo. Ahora el jurado está fuera sobre si necesitas ambos. El motivo por el que incluí el 14 y la lista, por supuesto, es que en la lista, las asignaciones de licencia, quiero mostrar el nombre de la licencia y el d, El nombre de la licencia y el nombre del tipo de hoja muerta y el dy. Por lo que necesitaría incluir aquí los detalles. Y luego si estás viendo uno de ellos, te gustaría ver los detalles también. Así que acabo de hacer eso e hice lo mismo. Y cuando estás trabajando con muchos de nosotros, necesitas navegar rápidamente. Entonces solo voy a usar esta flecha azul arriba aquí para sincronizar tienda este documento es rápidamente y luego dejar solicitudes. Ya ves que tengo métodos similares porque en las solicitudes de licencia necesitamos saber qué tipo de licencia se está solicitando. Y si estoy viendo la lista, te gustaría ver este tipo de hojas se solicitó en esta fecha, etcétera. Está bien. Ahora bien, en cuanto a nuestras solicitudes de licencia, tengo otra sorpresa de diapositiva y espero que ustedes se hayan pillado y ya lo hayan hecho. Pero las consultas se ven bastante iguales. Pero en términos las solicitudes más bien, pero en cuanto al tipo de devolución, notarías que tengo solicitud de licencia solicitud detalle mostrando las solicitudes de licencia DTO, sin embargo, para la lista y discutimos por qué separaríamos los detalles antes. Contamos con solicitudes de licencia detalle de lista. Por lo que la lista está determinando una lista de los detalles especializados para la lista. Y entonces los detalles está devolviendo el detalle con mucho más detalle en él. Para las consultas. Preocupaciones similares por la lista de solicitudes de licencia, manejador de solicitudes. Por supuesto que está devolviendo la lista de solicitudes de licencia DTO. Y el manejador luce palabras bastante similares llamando a un repositorio de solicitud de eliminación y llamando a las solicitudes de licencia get con detalles similitud. Cuando estamos viendo el manejador de detalles, es lo mismo excepto que estamos regresando solo el detalle de las solicitudes de hoja, el laboratorio configurando esto, podrías haber notado que estás obteniendo muchas líneas rojas cuando 're tipos desemparejados. Y si tuvieras el tipo de datos incorrecto aquí o lo incorrecto solicitaría que se hiciera referencia al tipo, todo se rompería. Entonces es muy, muy estricto. Si me dijo que la solicitud está esperando solicitud de tipo de licencia DTO, no puede poner ningún otro tipo de datos aquí en ese manejador que le está diciendo debe atender esa solicitud. De acuerdo, así que puedes ser muy, muy cuidadoso con eso. Y una vez que te acostumbras al patrón, estas cosas vendrán de manera más natural. Sólo puedo asignar si inicialmente es un poco frustrante. Pero una vez más, tienes el código al que hacer referencia para que siempre puedas simplemente pausar cuando necesites y replicar estos bits de código en tu aplicación en consecuencia. Ahora en nuestra siguiente lección, vamos a ver cómo configurar nuestro primer comando. Y el comando una vez más aumentaría los datos en la base de datos. Entonces vamos a ver lo que se necesita para configurar, crear comando para cualquiera de nuestros objetos de dominio. 10. Crea comandos con MediatR: Bienvenidos de vuelta chicos. En esta lección vamos a estar echando un vistazo a configurar comandos. Por lo que los comandos vuelven a aumentar los datos y vamos a estar empezando con o crear comando. Ahora si estás mirando mi Explorador de soluciones, notarías que tengo algunos archivos más y tengo una carpeta D2L reestructurada. Entonces déjame simplemente colapsar todo lo demás para que puedas enfocarte en esa sección. Por lo que en las primeras etapas de planear este tipo de arquitectura, siempre vas a estar cambiando las cosas porque es bueno hacerlo bien desde null a diferencia de más adelante cuando tienes muchos archivos diferentes y más, para instancia, las actualizaciones cuando se mueve, estos otros archivos son propiedad. Por lo que en las primeras etapas de configurar los detalles, había indicado que probablemente querrías tener una carpeta para los detalles y luego tener los diferentes tipos de detalles ahí dentro. Entonces lo hicimos con las solicitudes donde teníamos las solicitudes de licencia D2 y eliminar solicitudes lista detalle en lugar dejar carpeta de solicitud. Por lo que acabo de extender ese concepto a los otros detalles donde tengo una carpeta de asignación de permisos y carpeta tipo elif y nombre a esta hoja ese detalle profundo. Permítanme que lo corrija. Por lo que dentro de estas carpetas, vamos a tener los diferentes detalles. Y una vez más, no es absolutamente necesario que tenga múltiples detalles o detalles específicos de un propósito. Pero les voy a mostrar por qué es beneficioso hacer eso a veces. Por lo que con el tipo de hoja, el riesgo es bajo. Tenemos detalle de hoja. Todo lo que requiere es un nombre y el número predeterminado de días. Eso para mí, eso es simplemente suficiente. Este dato corre muy poco riesgo de sobreexponer cualquier cosa para cualquiera de las operaciones que podemos crear fácilmente usando este detalle, podemos listar fácilmente y podemos mirar los detalles. Es muy sencillo. No obstante, con las solicitudes de licencia, habíamos discutido que las solicitudes de licencia DTO tiene mucho más detalles en ella. En una configuración de lista, no necesitamos tantos detalles. En realidad solo necesitas los detalles del tipo de hoja solicitada, la fecha en la que se solicitó, y si está aprobada. Ahora en el Create, una vez más no necesitamos pedir al consumidor que proporcione todos esos detalles. Porque si comparas solicitudes de permiso de creación de dientes, realmente no necesitamos la opción de fecha. Y cuando alguien está creando una solicitud de licencia, cuando estoy pidiendo una licencia, no hay acciones de fecha. Por lo que no hace falta que se proporcione eso. La fecha solicitada que puede ser puesta por nosotros, por el sistema. No necesitamos obtener eso del usuario ni del consumidor. El inicio y la fecha de fin corto. Esos son esenciales. Necesitamos conocer el tipo de hoja. No necesitamos conocer todo el objeto del tipo de hoja. Sólo necesitamos el identificador del que se está solicitando. Y en ese punto, no está aprobado ni cancelado. Por lo que puedo tener un detalle específico y como estoy hablando, estoy viendo que tengo extra fusionando esto, pero tengo un crear leave requests DTO, que va a tener la fecha de inicio, la fecha de fin, el identificador para el die de hoja siendo solicitada. Y una vez más, el sistema puede ver la fecha solicitada. Y necesito hacer de esto en realidad un nullable. Entonces voy a aprovechar esta oportunidad para ajustar esto. Entonces esto necesita ser nulable, pero no necesito al remitente en el Creates. Yo lo tomo todo junto, creo en la solicitud de licencia, voy a hacer que sea anulable porque regla de deducción realmente significa cuándo fue aprobada o cancelada. ¿ Verdad? Y entonces de igual manera, solo voy a hacer esto hasta el dominio. Una vez más, es bueno ver estas cosas temprano y ajustarlas porque aún hicimos la base de datos, así que no tenemos que preocuparnos de que esto se desgarre demasiado. ¿Todo bien? Entonces por eso tengo un DTO específico para crear la solicitud de licencia, diferente al listado, diferente a los detalles. En otro, cuando tenemos la asignación de licencias y desasignación tiene una serie de éstas, los detalles del tipo de hoja que se relaciona con ella, identificador y el periodo. Es similar a la solicitud de licencia. No necesito los detalles del tipo de hoja al tipo de momento de creación. Entonces cuando hablamos de sobre la publicación, significa que estamos dando a la aplicación cliente la oportunidad de proporcionar demasiados datos. Y luego aquí es donde hackear y malos datos y personas introduciendo anomalías en tu base de datos, así es como eso sucede. Por lo que esta es una buena manera de restringir lo que puede suceder en una operación. Entonces sepan eso. Tener una buena comprensión de por qué tenemos más detalles introducidos. Echemos un vistazo a los comandos. Entonces voy a empezar con el más fácil, que son los comandos de tipos de hojas. Voy a ir a solicitar y voy a crear una nueva clase. Y este Gaumont va a ser muy específico crear solicitud tipo hoja. Entonces esa es la petición de crear un tipo de hoja y se fue a seguir adelante y agregarla y convertirla en una clase pública. Y entonces éste está heredando como sabemos de yo solicito. Y volverá, voy a hacer que devuelva un entero 0. Este entero será. el nombre o lo siento, ha creado el nombre o lo siento,el ID del valor o el registro. De acuerdo, así que creas, solo te vamos a decir la identificación de lo que lo creas. No sabemos qué puede necesitar hacer el cliente después de la creación, pero les estamos dando pero la ID guardada, necesitan ir a la página de detalles después. Eso depende de ellos, pero les estamos diciendo que fue exitoso. Aquí está el DNI para el nuevo registro. Ahora en el comando, lo que vamos a tener, como sabemos mi nulo es nuestro manejador de coincidencia para esta solicitud. Por lo que heredamos de solicito manejador. Y solicito manejador va a estar implementando la solicitud de crear tipo hoja. Adelante e incluye cualquier cosa que falte. Y verá que está devolviendo un entero. Ahora cuando implementemos la interfaz, verás que conseguimos que esa tarea devuelva un entero y nuestro manejador. Ahora volvamos a saltar un rato a sus peticiones. Y hay pocos patrones que podrías ver en la solicitud de creación. Un patrón es que la gente realmente escribiría todos los campos que cuando estás a punto de crear un registro para este año, enviando las solicitudes para crear registro para ese tipo. Pondrían en los campos en la solicitud real para ver estos son los honorarios que se te permite enviar con la solicitud. Y entonces en ese momento, esa solicitud sirve básicamente al propósito de mi detalle que acabo de definir aquí. No, yo personalmente, no me gusta mezclar y emparejar. No me gusta tener detalles aquí, pero entonces cuando es yo creo, tengo los campos aquí. Y entonces, ya sabes, no sé a dónde ir y necesito cambiar lo que va a veces no recuerdo. En cambio, mantengo todo a nivel de detalle y la solicitud es realmente solo un mecanismo para transferir los datos. Por lo que el DTO representa los datos y la solicitud es justo ese transporte. Con todo lo dicho, voy a presentar nuestro inmueble en esta solicitud de licencia tipo DTO. Por lo que este inmueble es lo que el consumidor llenará con la solicitud y la enviará. Entonces en nuestro mando sabemos que decimos solicitar diabetes de hoja de punto, ahí es donde están los datos. Entonces por supuesto, si vamos a estar interactuando con tipos de hojas y automapeador, entonces necesitaremos que nuestros sospechosos habituales en nuestro constructor sean inyectados. Y para la velocidad de nuevo, esos vuelven a uno de los manejadores existentes y solo copian y pegan, cambian el nombre del constructor. Y luego solo incluimos cualquier referencia que falte. Está bien, para trabajar más inteligente, no más duro. Entonces ahora que tenemos todas las herramientas que necesitamos, ¿cómo configuramos nuestro manejador para crear este registro? Pero antes de seguir adelante, voy a hacer un ligero ajuste. Entonces otro patrón que verás, y creo que voy a usarlo esta vez sólo porque es para mí, es más limpio en lugar de solicitudes. Entonces cuando estamos lidiando con comandos, no, no va a ser nuestra petición porque yo solicito es cuando estás pidiendo algo, ese comando es cuando estás diciendo algo. Quieres un mando. Entonces en lugar de nosotros usando solicitud en el nombre aquí donde decimos crear comando tipo hoja. Muy bien, Así que al cambiar el nombre de la fuente, puedo cargar el IntelliSense para renombrarlo en todo el tablero, pero renombraré el archivo manualmente. Por lo que tenemos crear comandos tipo hoja, así que sabemos con certeza que éste es un comando y es obviamente el manejador se supone que está llevando todo su comando. Entonces Comando Entrar, está bien, y actualizar cualquier otra referencia está en el lugar. Entonces creo que en realidad es más limpio y más fácil en los ojos. Es un distinguido entre lo que solicito clases sobre lo que nuestras clases de mando resuelven para nuestra operación. Lo que vamos a hacer es definir el tipo de hoja a ser igual. Y luego solo vamos a usar auto mapper para mapear en tipos de licencia. Por lo que estamos mapeando desde el detalle hasta el objeto de dominio esta vez el nuestro. Por lo que mapeador Dartmouth tipo de hoja, entrelazado tap nuestra mirada a petición punto hoja tipo BTO. De acuerdo, así que solo sigue adelante e incluye cualquier cosa que falte. Ahí vamos. Entonces ahora decimos que el tipo de licencia es igual para conseguirme la versión trapeada de eso en el objeto de dominio. Entonces llevamos a cabo nuestro, esto va a decir tipo de licencia es igual a y nuestros pesos en vamos a llamar a nuestro repositorio tipo hoja dot add method blocks, ¿verdad? Entonces recuerda que en realidad está devolviendo el objeto o algo del mismo tipo de datos, ¿verdad? Entonces deje tipo ahora se va a actualizar porque después de Entity Framework, que es lo que vamos a estar usando como nuestro RM. Después de que haga su operación se va a actualizar el ID. Por lo que estamos devolviendo el objeto con ID actualizado y sabemos que tenemos esa ID. Podemos decir retorno, tipo de licencia, ID de punto. Ahí vamos. Entonces sepan que se ha manejado el mando. Nolan, lo miramos, vemos que realmente no fue tan complicado de hacer. Son solo tres líneas donde obtener la solicitud con los datos. Y luego lo vamos a mapear a los objetos de dominio. Vamos a entonces jefes o dentro de un repositorio o para que se produzca la operación. Y entonces sólo estamos devolviendo la idea y eso es todo para el comando create leaf type. Por lo que en realidad puedes simplemente hacer una pausa aquí y pedirle que lo haga con los demás. Yo lo voy a hacer y luego podemos comparar notas. De acuerdo, así que me he saltado adelante y he ido adelante e implementado los comandos que crean comandos para los otros dos objetos de dominio. Entonces si lo miras con cuidado, ves que es más o menos la misma cita aparte de los nombres y los repositorios involucrados, es más o menos el mismo código. Entonces este es el manejador de comandos leave allocation. Puedes hacer una pausa, puedes replicarlo si es necesario. Pero ese es nuestro creador manejador y nuestra búsqueda de carrera. Simplemente tomando que crear dejar detalle de alegación en lugar del detalle de alegación de licencia. Está bien. De igual manera para la solicitud de licencia, mismo código, misma estructura, ¿no? Y luego el comando, solo está tomando el detalle de solicitudes de licencia para crear el detalle de solicitud. Entonces ves que todo este tipo de luce muy similar. Para que puedas seguir adelante y replicar los de tu código. Y cuando regresemos, veremos los otros comandos que incluirían actualizar y eliminar. 11. Terminar los comandos con MediatR: Muy bien chicos, bienvenidos de nuevo. Como notaste, mi pantalla está en blanco. En esta lección, vamos a estar hablando de agregar los manejadores de actualización y eliminación y todos los activos que van con ellos. Entonces mi pantalla está en blanco porque he agregado bastantes activos y voy a pasar por ellos uno por uno contigo y puedes seguir adelante y replicarlos. Pero quiero que entendamos las decisiones que estamos tomando en este punto ya que son decisiones críticas. Y este tipo de arquitectura, las cosas que pones ahí, todo basado en decisiones. Una vez más, son relativos a lo que estás trabajando, tu equipo y a la aplicación general sobre lo que esperas lograr. Entonces, empecemos mirando los detalles. ¿ Dónde están? Pasó por los detalles y tipo de los separamos por carpetas para que podamos ver todos los detalles relativos a un tipo de dominio con bastante facilidad. Pero entonces en este punto, teníamos un VT0 para el tipo de hoja, y habíamos dicho que, vale, eso era de bajo riesgo porque podía ser utilizado para muchas operaciones diferentes. Desde entonces lo he roto en dos. Y la razón de esto es que has creado hoja tab2 diferente a la hoja tipo D2 y todo. ¿ Por qué? Debido a que el detalle tipo hoja hereda del detalle base y la base D2, recuerda nos da el ID, conoce el riesgo de esto. Y una vez más, propósito del detalle es reducir tipo de lo que llamaremos sobre la publicación. Si estoy creando un tipo de hoja, no necesito una identificación. No quiero darle al consumidor la capacidad de proporcionar una identificación porque eso solo daría problemas. Les estoy dando exactamente lo que necesitan para superar su operación. Por lo que creé un nuevo detalle para tipo hoja donde solo obtienen nombre y escrituras por defecto. No pueden proporcionar un campo de identificación. Detalle tipo hoja se puede utilizar para todo lo demás, para editar, para ver porque bueno, tiene esos campos así como BCE, que es el ID. Ahora, como puede terminar obteniendo más y más detalles y tienes sensación repitiendo a través de los diferentes detalles, entonces tal vez quieras considerar tener una carpeta común dentro de esa subcarpeta ya para tipo de definir esta propiedad es que este detalle debe tener de todos modos. Por lo que cualquier hoja tab2 que surja más hafnio y debe tener días por defecto. Podrías definir una clase base si lo necesitas. De acuerdo, ahora podemos pasar a las asignaciones de licencias tener tres detalles de asignación de licencias en este punto, y voy a señalar un error que cometí en uno de ellos. Este error fue tener crea detalle de asignación de licencia heredando de este detalle. Está bien, así que hay que tener cuidado con estas cosas si estamos tratando de ser estrictos. Entonces eso fue un error de mi parte. Crear detalle de asignación de licencia una vez más no debe tener absolutamente ninguna referencia a ninguna clave primaria en absoluto. Pero entonces sí necesitamos los otros campos. Las actualizaciones, sin embargo, sí necesita acceso a la DTO base para nuestros propósitos de actualización. Ahora, podría ser que dijimos, vale, bueno, una vez más, crear ese detalle base del que todo el mundo hereda. O podríamos simplemente morder la bala y decir usaremos 14 crear o actualizar si se proporciona el ID y sabemos que es una actualización si no se previene y asumimos que es yo creo, esos podrían ser fácilmente argumentos que no estoy viendo, no, no estoy viendo que sí. Depende de lo granular que quieras obtener y estas son tus decisiones que debes tomar en base a tu contexto. Solo estoy señalando las diferencias y los riesgos en consecuencia. Entonces los voy a estar sacando así. No Por solicitud de licencia pasa incluso por otro nivel. Por lo que sí tenemos el detalle de solicitud de licencia donde familiarizado con eso. Tenemos el detalle de lista el cual ya estableció por qué eso es diferente. Tenemos el Create que una vez más es incorrectamente, al menos en mi contexto heredando de esto, que voy a caracterizar nulo. Y entonces tengo que haber actualizado el Detalle de la solicitud diferente de licencia cambiada solicitar detalles de aprobación? No, vas a preguntar. Está bien. Entonces, ¿por qué tener ambos? Porque ambos están hablando de aumentar los datos. Está bien. Bueno, una vez más, es cuestión de host engañado quieres ser por lo que la actualización sirve para el propósito de permitir que el usuario o el consumidor permita al usuario final actualizar sus solicitudes. Querían tal vez cambiar las fechas de inicio o el final tal vez eligieron vacaciones cuando esto debió haber elegido enfermo. A lo mejor quieren poner nuevos comentarios o simplemente quieren cancelarlo. Entonces les estoy dando exactamente lo que pueden hacer usando este DTO si envían su solicitud para actualizar. Estas son las únicas cosas que se pueden actualizar. No obstante, aprobación de licencia de cambio. Solicitar, perdón, dejar solicitud de aprobación detalle, lo siento, tendría sólo la capacidad de cambiar. Está aprobado DSR null. Entonces el aprobador en realidad sólo está diciendo que sí o no. Es decir, si tuvieras más campos como comandos adicionales y cualquier cosa que pudieras agregarlos a DTO. Por supuesto, tendrían que ser presentados los objetos de dominio. Pero mi punto es que estoy usando el detalle aquí para ayudarme a hacer cumplir ciertas reglas de negocio y ciertos comportamientos que mi aplicación es capaz. Y, y una vez más, he visto situaciones donde hay un plano D azulado y se toman decisiones en el 100 que en base a los datos presentes, tal vez en la solicitud estén al detalle. Este es el tipo de operación a realizar. Por lo que depende de cuánto quieras romper ETL para tener ese nivel de granularidad. Entonces ya saben, si se trata de una aprobación solicitada, sepan exactamente a qué manejador acudir. O puedes tener un manejador de comando grande que está tomando los datos y un montón de sentencias si para ver si es, si el ID está presente, entonces si no está presente, entonces sí, Pero entonces si está presente y esta bandera no está nulo, entonces asuma que es una aprobación. Podrías hacerlo de esa manera, pero yo no lo estoy haciendo de esa manera. Prefiero saber que cuando se trata de una solicitud de aprobación, tengo ese comando de aprobación de cambio. Si se trata de una actualización, es un comando de actualización y saber exactamente a dónde ir para hacer qué. Entonces ahora que tenemos esa explicación detallada fuera del camino, voy a saltar a las características, carpetas en futuros, en asignaciones de licencias y tipos de dejar al menos ya he definido los nuevos manejadores y sus comandos. Entonces echemos un vistazo a la más simple. Por lo que tenemos el comando update leave type. Y este comando para el tipo de hoja solo está tomando nuestras peticiones están heredando de Eric quest como sabemos, pero luego está devolviendo lo que llamaremos una unidad. Entonces si simplemente pasas por alto, necesitas ver que se trata de un constructo provisto de mediador que no representa nada como vacío, ¿verdad? Sin contenidos. Entonces en el diseño de API, cuando haces una actualización, normalmente regresarías a 202, si no me equivoco, lo cual es abreviado de ningún contenido. Entonces significa que fue exitoso, pero no tengo nada que mostrarles. Eso es básicamente lo que es la unidad. Y luego estamos tomando esa hoja tipo DTO como propiedad. Todavía no he implementado los comandos en los manejadores, así que podemos hacerlo juntos. Solo estoy demostrando que tenemos ese mismo constructo para el comando update leave allocation, donde estamos tomando el detalle de asignación de licencia de actualización y devolviendo esa unidad. Y tenemos ese comando definido en consecuencia, también vacío. Entonces vamos a hacer esos dos juntos porque esos son bastante simples. Y luego vamos a pasar algún tiempo explorando las solicitudes de licencia y las reglas de negocio ahí. Ahora el flujo de trabajo para nuestro manejador, y voy a empezar con el manejador de comandos tipo hoja. Muy bien, el flujo de trabajo aquí es que necesitamos querer recuperar el registro original para actualizar ese origen se requieren y luego tres, enviarlo todo a la base de datos y luego devolver la unidad, o al menos algo para decir que era exitoso. Por lo que dos enfoques. Uno, se puede utilizar el repositorio para tener ese método específico porque entonces en el caso de las solicitudes de licencia, podría haber métodos específicos. Y luego una vez más, vas a bajar ese juguete de conejo apagado. Tener métodos muy, muy específicos en cada repositorio a lo largo de la línea. O simplemente puedes hacer la mayor parte del trabajo dentro de un manejador, que es para lo que sirve de todos modos. Está bien. Entonces solo voy a decir var tipo de licencia es igual a dejar repositorio de tipo, Git. Y luego estamos buscando en la solicitud, buscando en la hoja para estar mirando el DNI. Ahora, otro patrón de diseño que he visto es cuando es un comando de actualización tipo hoja, usarían el tipo de hoja regular, digamos el que no tiene el ID, pero luego poner la propiedad ID dentro de la solicitud o el comando objeto para que nosotros, cuando usted está haciendo la actualización para incluir el ID dentro de este objeto. Y entonces el detalle es justo en sí mismo. Hay tantas maneras de hacer esto. Y una vez más, los que entiendas lo que estás haciendo, me pueden hacer la mejor implementación en base a tu contexto. Aquí. El tipo de licencia se va a recuperar en base a la identificación fuera de la carga útil que entra con la solicitud. Y entonces podemos ver mapeador no MOP. Y luego mapeador dot map es más o menos sólo va a, en esta situación, obtener la solicitud pensamiento hoja tipo D2. Y note que no estoy especificando, necesito teclear esta vez. Estoy usando paréntesis, mapa de puntos mapeador, paréntesis abiertas. Y entonces estoy viendo que esta es la fuente de los datos. Y quiero que el tipo de hoja que acaba de ganar de la base de datos sea el destino de los datos. Y estoy consiguiendo esa línea verde porque fallé A ella en la línea. Pido disculpas. Entonces ahí vamos. Entonces mapper dot map y luego lo ve por favor solo actualiza lo que esté a la derecha con lo que esté a la izquierda, eso podría ser diferente si es diferente o no, esto, por favor actualízalo porque la actualización se va a enviar de nuevo. Y es por eso que nuestro detalle necesita tener tantos campos que tanto los datos, el objeto de dominio en sí como sea posible. Está bien. El nombre de Dava va a tener días por defecto. No sabemos qué ha cambiado, así que por eso estamos viendo el otoño superior, solo actualizar todos los valores. Si ese Blanco el nombre, entonces lo vamos a actualizar a un nombre en blanco. Ojalá no lo hicieran. No obstante, si no cambiaron de nombre, entonces la expectativa es que el mismo nombre vaya a volver. Entonces, una vez más, no podemos dar cuenta de lo que pudo haber sido la barbilla. Por lo que solo estamos viendo, por favor actualice el tipo de hoja con los valores correspondientes provenientes del objeto de la izquierda. Y luego vamos a ponderar nuestra actualización de repositorio neve. Y entonces aquí es donde enviamos nuestro mapeo de postes tipo hoja o enviándolo a la Actualización. Y luego solo devolvemos valor de punto unitario. Y eso es todo. Esa es nuestra operación de actualización. Bueno, tengo esta línea roja aquí arriba porque tengo int y no unidad. Entonces después de mí ese cambio, todo está bien. Entonces eso es para la obesidad en el tipo de hoja o qué? El tipo de hoja. Entonces en realidad sólo voy a copiar esto. No me voy a dar demasiado trabajo. Voy a saltar para actualizar asignación de licencias. Y lo único que vamos a estar haciendo de manera diferente aquí es que en lugar de usar el repositorio tipo hoja, voy a estar usando el repositorio de asignación de licencias. En lugar de ver hoja tipo DTO, estoy viendo asignación de licencias BTO. Y en lugar de llamar al tipo de hoja de objeto, lo estoy llamando asignación de permisos, todo lo demás es bastante estándar y casi igual. Y esto manejará nuestra solicitud de actualización. De acuerdo, así que he ido adelante y completado los comandos leave request para actualizar LaCo, vemos no que no sea tan complicado o así he ido adelante y he hecho el comando update leave request y el manejador correspondiente. Por lo que nuestra licencia solicita manejador de mando tomado de la unidad de devolución de mando. Y es sólo conocer la diferencia una vez más, es el repositorio que se está utilizando, pero es prácticamente la misma operación. Ahora una cosa que tal vez quieras considerar son las reglas de negocio específicas, nuestras propias este tipo de operaciones. Entonces sí, el código, se ve igual, pero luego al actualizar una solicitud de licencia, podría haber otras cosas que tengan que suceder. Correcto. Por lo que en el caso del cambio, solicitar, cambiar y dejar solicitar aprobación donde solo obtenemos aprobación o no. También necesitamos establecer la acción que también necesitamos para actualizar probablemente algunas otras cosas. Entonces creo que serás bueno si tuviéramos una función específica en nuestro repositorio para manejar la solicitud de cambio. Ahora lo genial de las solicitudes es que no necesariamente tenemos que tener nuestra solicitud por hora solicitudes por todo el tiempo. En realidad podría reutilizar la misma solicitud y manejador para manejar este tipo de operaciones. Entonces veamos esta situación. Por lo que dentro de la actualización, dejar, no dejar asignación, disculpas, dentro de la licencia solicita comando, podríamos tener las solicitudes de licencia DTO, pero también podría tener una propiedad de tipo cambio de licencia solicitar aprobación DTO. Por lo que esta solicitud es capaz de tener alguno de estos objetos. Ahora en el manejador, puedo tomar una decisión y llamar al método apropiado en base a esto porque sigue siendo un comando de actualización, ¿verdad? Por lo que dentro de este manejador de comandos de actualización, puedo poner un poco más de lógica. Puedo ver si request dot leave request detail no es igual a null, entonces esta es la ruta que deseo tomar. Puedo ver otra cosa. Y voy a acelerarlo muy explícito con esto más porque no sé si tal vez en el futuro pueda tener algunas otras reglas de negocio. Entonces solo me voy a conformar con estas dos situaciones explícitas donde o es que el esto debe ser else-si disculpas, de lo contrario, si de lo contrario si solicita cambio de punto, solicitar aprobación D2 no es igual a nulo, entonces hacer eso, ¿verdad? Y luego las horas extras iban a intentar y rutinario uno regresa. Entonces me voy a llevar todo esto y decir que llevas a cabo esta operación cuando el detalle de las solicitudes de licencia no es igual a nulo. Por lo que eso significa que quien esté consumiendo a quien esté interrumpiendo con este manejador enviando su solicitud necesita asegurarse de que el relleno. Los campos apropiados de acuerdo a lo que quieran. Algunos simplemente mostrando unos sabores diferentes porque podía ir al RequestHandler peering para cada situación, cada escenario individual, pero entonces se puede hacer un poco a granel juntos, como dije, el manejador. Algunas personas ponen mucha lógica empresarial en esta sección. Entonces, una vez más, eso depende de ti. Entonces si el cambio licencia solicitud aprobación DTO no es igual a nula, tenemos una decisión que tomar. ¿ Qué exactamente vamos a hacer? Sabemos que hemos recuperado y dejamos solicitudes de una forma u otra. No vamos a hacer el mapeo integral que realmente queremos hacer se llama eventualmente los barcos de actualizaciones con otras cosas que suceden. Entonces voy a llamar a espera, dejar solicitudes, repositorio, cambiar estado de aprobación. No. ¿Qué hacemos? Podría darle el DNI. Podría darle el objeto de solicitud de permiso, así como el estado al que debería cambiarse. Hay una serie de enfoques que podemos tomar. No. Siempre hablamos de repetir código, ¿verdad? Entonces digamos que hago esto, voy a buscar las solicitudes de licencia. Y entonces esto sería relativo al cambio, la solicitud de aprobación detalles ID. Y entonces puedo decir dar a esta operación las solicitudes de licencia que también se recuperó. El valor del campo de detalle para la aprobación, sea aprobado o no. Está bien. No, estoy repitiendo esta llamada para obtener una solicitud de licencia. No, solo puedo hacer esta llamada relativa a si fue la solicitud el TOR cambió solicitudes de licencia detalle que entró porque si esto se sabe, entonces no puedo obtener esa identificación. Y si esto es nulo, entonces después de tomar una decisión. Entonces, ¿ves todas estas otras cosas? No. De acuerdo, vamos a refactorizar. Entonces para facilitarnos la vida, vamos a volver al mando. Y luego fui a decir, bueno, no, veo buena razón para hasta que el consumidor incluya el DNI. El DNI debe estar presente de cualquier manera, pero sí incluir el DNI aquí. Entonces cuando incluyes el ID ahí, puedo decir fácilmente request dot ID desde fuera del bloque if. Y entonces sé que tengo las solicitudes de licencia que hay que modificar. Ahora bien, si es que todo el detalle GameOver, entonces bien. Sé exactamente qué hacer si es solo la solicitud de cambio. No tengo que ir a encontrarlo específicamente, pero entonces ya lo tengo y solo puedo pasar en el estado de aprobación. Por lo que este método se puede implementar en nuestro Voy a dejar repositorio. Y yo sólo lo voy a hacer vacío. Entonces es sólo esa tarea. Y los parámetros serían DV, request y un booleano. Bueno, tiene que ser booleano nullable de estado de aprobación. De acuerdo, entonces cuando llamamos a eso, sólo estamos pasando esos dos comandos apropiadamente. Entonces esta es una forma de escribir el código. Seguro que probablemente estás sentado ahí y diciendo, vale, probablemente lo podríamos haber hecho de esta manera o necesito hacerlo de esta manera para mi situación, está bien. Pero siempre y cuando entienda la flexibilidad que tenemos cuando se trata toda esa canalización de manejador de solicitudes y cómo podemos manejar diferentes escenarios. Podemos utilizar el manejador de un solo para manejar los diferentes escenarios potenciales basados en la solicitud, en base a los datos proporcionados en la solicitud. Y, ya sabes, no tienes que tener peering para cada escenario que puedas tener, pero puedes tener un manejador para cubrir múltiples escenarios. De acuerdo, así que ahora que tienes el colgado de ello, quiero que sigas adelante e implemente el delete commons y handlers. Entonces he ido adelante y hecho eso. Y tenemos el comando Eliminar tipo hoja, que está heredando de las solicitudes de IO. Por lo que note no tengo solicito y datatype la última vez que utilizamos las unidades. Entonces este es solo el 0 que no necesariamente tienes que poner en ese tipo de datos si no se supone que esté devolviendo nada. Por lo que este comando delete tendrá un parámetro para el ID. Y luego dentro del manejador, todo lo que estamos haciendo es recuperar el apropiadamente basado en el ID, y luego lo estamos enviando a la eliminación y luego solo estamos regresando unidad. Y en este punto ese es el tema general para el centro comercial. Entonces es lo mismo para la solicitud de licencia. Sepa si realmente va a exponer funcionalidad para eliminar una solicitud de licencia. Eso depende enteramente de tus reglas de negocio porque podría ser que no haya borrado duro, solo es un soft delete o delete realmente significa cancelar, ¿verdad? Por lo que eso simplemente lo señalaría que fue cancelado, desatendido, pero mantener el registro. Entonces solo te estoy mostrando cómo poner en la funcionalidad. Pero entonces una vez más, las reglas de negocio y la aplicación de las mismas son relativas a su situación. Entonces eso es todo para configurar los manejadores de eliminación y actualización para nuestros objetos de dominio. Y más o menos esa es la esencia de todo el patrón mediador acoplado con el C QR está salpicado. Entonces a medida que avanzamos, lo que vamos a explorar es hacer que esto sea un poco más a prueba de balas porque ¿verdad? Conoce cualquier cosa puede pasar, cualquiera puede venir y crear cualquier cosa, y no hay reglas reales para gobernar lo que es válido versus lo que es inválido. Entonces intentaremos ver ese conjunto que manejamos datos inválidos entrando y cómo podemos hacerlo un poco universal e infalible. 12. Agrega Validación: Muy bien chicos, bienvenidos de nuevo. En esta actividad estaremos configurando la validación para nuestros detalles y nuestros comandos. Ahora antes de seguir adelante, hay unos carros rápidos sobre nosotros que quería hacer para el código que escribí en el comando de actualización leave requests. Había usado inadvertidamente el detalle de las solicitudes de licencia. Entonces si está en la actualización, entonces debes ser adoptado hoja Solicitar detalle. Entonces si captaste ese error y te lo hiciste a ti mismo, entonces te lo honraste. Si no, entonces puedes seguir adelante y reunirte. Esto me cambia. No hay problema. Ahora de lo que estamos hablando cuando nosotros, en el tema de validación es la capacidad de asegurarnos de que los datos que estamos recibiendo antes de que entre en la base de datos sean bien válidos porque tal como está, hay nada aquí que nos detenga de comprometer, invalidar una base de datos de juguetes. Y una cosa que es muy, muy, muy importante es la integridad de los datos. Por lo que no quieres crear dos registros con datos vitales faltantes asignación de licencias. No sabemos qué tipo de licencia. Sigue siendo plano en eso, por lo que querrás validarlo y luego rechazarlo por supuesto, si no cumple con los estándares. Ahora, cuando estás acostumbrado a MVC y crees que la validación TBL y estás viendo que en los modelos podríamos fácilmente poner nuestras anotaciones de datos, lo cual es muy cierto. He encontrado que esto es útil. Pero entonces cuando se quiere extender más allá de las predeterminadas, hay que empezar a construir antiguas extensiones y sal, que es, que también es muy bueno. Pero entonces en este programa en particular, vamos a estar usando validaciones fluidas, que es una biblioteca que nos permite utilizar la sintaxis fluida y billowed muy, muy poderosas reglas y estructuras de validación son propiedad de nuestras propiedades en nuestro clases. De acuerdo, así que para empezar, vamos a saltar hacia el nuevo Git y supongo que bastante buscado con fluidez. Y ves que aparecen todos estos maravillosos resultados de búsqueda. No hay punto de información. La documentación para esta biblioteca es muy buena y la puedes encontrar en el sitio web para la invalidación dotnet, y verás cómo podemos extender esto y masajearlo y usarlo a toda su capacidad para ayudar con sus necesidades de validación. Entonces voy a seguir adelante e instalar esta biblioteca para las extensiones de inyección de dependencia. Y una vez hecho eso, podemos cerrar NuGet y luego pasar a nuestra configuración. Pero una cosa a tener en cuenta, creo que no lo he mencionado antes. Al hacer clic en esos archivos CSB, en realidad ves qué paquetes están instalados en su versión. Por lo tanto, alternativamente, si conoces el nombre exacto del paquete y la versión que deseas, en realidad puedes pegar alineado así dentro de tu compilación de blob de archivos CSV y automáticamente obtendrá ese paquete de NuGet para ti. Entonces esa es una forma que también puedes instalar, resolver estos paquetes en el futuro. Entonces empecemos con nuestros validadores. Saber me preguntaba dónde poner estos validadores, solo voy a colapsar todo. Para que podamos ver todas nuestras carpetas tipo de comprimidas, ¿de acuerdo? Y entonces por supuesto tenemos los detalles. En los detalles es donde tienen que suceder nuestras validaciones porque son las que se atascan viendo la inflamación en nuestro nombre. No necesitamos validar las que se están utilizando para las consultas. Eso es algo inútil, ¿verdad? Porque las operaciones de lectura no necesitan validaciones. Las operaciones correctas o las operaciones de aumento, sin embargo, sí. Entonces voy a, en una de las carpetas, dejarme empezar con la más fácil. Voy a agregar y nueva carpeta. Y yo sólo lo voy a llamar validadores. Y luego dentro de esto, voy a añadir una nueva clase. Y entonces este va a ser crear hoja tipo D2 validador. Por supuesto, para hacerlo público. Y luego voy a dejar que herede de un validador abstracto. Y luego voy a pasar en nombre de la clase exacta con la que es relativa. Por lo que solo seguiré adelante e incluiré cualquier referencia que falte. Y luego agrega que usando validaciones fluidas biblioteca y luego estamos listos para irnos. Entonces lo que tenemos es un constructor. Entonces CTR tina, tina y conseguimos ese constructor y luego podemos empezar a definir reglas. Entonces déjame solo echar un vistazo rápido al crear hoja tipo D2. ¿ Qué quisiéramos validar en esto? Bueno, querría asegurarse de que los valores de nombre proporcionan derecho. También probablemente podamos limitar el número de caracteres que puede tener esta propiedad de nombre. Ya sabes, la mayoría de ellos no lo sabían, y debe tener una longitud máxima. Y probablemente querría mensajes personalizados para situación para el número predeterminado de días, probablemente podamos ver que es hostil, ser más, más de uno, debe ser mayor a 0, al menos para el número predeterminado de días. Por lo que hay una serie de cosas que podríamos validador. Entonces lo que veremos es la regla cuatro. Y luego notarás que este look solo deja las mismas expresiones lambda a las que estamos acostumbrados. Y si no estás bastante acostumbrado a ellos, está bien. Nos acostumbraremos a ellos eventualmente. Entonces es regla para y entonces podemos ver nombre. Y lo genial de la validación de Flint es que puedes encadenar las cosas. Entonces puedes encadenar ya está y decir: Vale, esta regla y esa regla y esa regla y esa regla. Por lo que la regla para el nombre de punto P. Está, digamos, no vacío. Entonces eso significa que debe tener un valor. Y entonces puedo decir con mensaje, así que si viene más de m2, entonces queremos que se imprima este mensaje. Entonces puedo hacer algo así como este nombre de propiedad para que no queramos hablar con. Tipo nombre debe ser su nombre es obligatorio, ¿verdad? Porque entonces estoy haciendo dinámico. Si cambiamos el nombre en la propia clase, entonces podemos olvidarnos de actualizar el mensaje en consecuencia. Por lo que al hacer esto, automáticamente heredará cualquier nombre o lo que sea que el nombre esté fuera de la propiedad, que realmente lo es también. Correcto. Por lo que diremos que se requiere nombre de la propiedad. Ese es nuestro mensaje de validación. Otra validación que podríamos poner no es nula. Entonces te estamos haciendo saber que esto no debe ser nulo. Y pongo mi punto y coma prematuramente, tan terrible que así tampoco debe ser nulo. Veamos qué podemos tener esos. También podemos decir que la longitud máxima de la propiedad de nombre es tal vez 50. No debe haber tipo de licencia con un nombre que exceda los 50, ¿verdad? Y luego podemos agregar otro con mensaje a eso con el mensaje. Está bien, así que solo te estoy dando ideas. Es decir, puede que tengas diferentes yo soy requisitos para tu validación que yo, pero estos son lineamientos generales que pueden seguir. Entonces veamos el, el punto por defecto p es. Entonces por defecto es que notarías saber que debido a que el tipo de datos es diferente, algunas de las validaciones podrían no aplicarse necesariamente. Entonces no puedo hablar de longitud máxima con el valor predeterminado es que no tiene nada que ver con un entero, ¿verdad? Ya ves que las flechas se han ido, así que lo estoy viendo debe estar presente, pero luego es entero, así que siempre, más o menos siempre estará presente, pero podemos dejar eso solo. Pero no debería estar vacío. Entonces nunca puede ser nulo. Realmente intuitivo porque los enteros son valores predeterminados 0 y los valores nulos proporcionados. Pero entonces sí vimos Eso es siempre debe ser mayor que 0. Y entonces estoy seguro de que hay un menos que. Entonces digamos que queremos ver en el sistema no debe haber ningún tipo de hoja que sea Putin que tenga cualquier número de estos Greta que un 100 o hasta un 100. Y debe ser al menos uno. Por lo que los diferentes tipos de datos pueden obtener diferentes reglas y podemos encadenarlos solos según sea necesario. Podemos poner nuestros mensajes en consecuencia para que pueda poner mi mensaje aquí con mensaje aquí. Entonces con esas validaciones en su lugar en la hoja tipo DTO, veamos cómo podemos ir para asegurarnos de que estas validaciones sean nuestras propias. Entonces en el comando que crea el tipo de hoja, correcto, sí obtenemos esa hoja, esa BTO de nuestro objeto de comando, ¿verdad? Pero lo que voy a hacer antes incluso de hacer el mapeo, porque no quiero desperdiciar recursos en una operación con datos inválidos. Entonces voy a hacer primero la validación. Por lo que voy a decir var validador es igual al validador de tipo New Leaf DTO. Entonces si bien sigue siendo un detalle antes de intentar incluso mapearlo al tipo de dominio, voy a invocar ese validador al que voy a decir resultado de validación var es igual. Y esperaré a mi validador haciendo la llamada para validar. Y tenemos la opción asíncrona, ahí usar el await. Y luego pasamos en el objeto a validar, que será una solicitud puntos dejan tipo DTO. En este punto, el resultado de validación va a tener o bien flechas no lo son. Entonces voy a ver si el punto de resultados de validación es válido, así que obtenemos que o sea válido o no en base a las reglas. Va a ser válido o no. Si lo es. Digamos si no es válido. Y luego para la legibilidad, quería decir si es válido es igual a falso, ¿verdad? Porque a veces con toda justicia, cuando solo usamos signo de exclamación, a veces cuando estás cansado, emiten incluso te lo pierdes cuando estás revisando el código y así sucesivamente. Entonces solo voy a ser un muy explícito si es válido es equivalente a falso, entonces simplemente voy a lanzar una nueva excepción. Entonces si estás acostumbrado al manejo de excepciones, se lanza la excepción, eso es todo, básicamente se bloquea. El programa sabrá más adelante veremos un mejor manejo de excepciones y todo eso en realidad nos puede ayudar a escribir un código un poco más limpio. En lugar de ayudar a un montón de declaraciones if a revisar un montón de cosas, sólo tenemos excepciones. Ese es nuestro ser a través y estratégicamente ayudar al flujo de la aplicación. Entonces en esta situación, si no es válida, entonces sólo vamos a lanzar una excepción. Vamos a ver cómo podemos hacer excepciones personalizadas también, que se pueden manejar de manera diferente a las excepciones fetales reales. Entonces eso es más o menos. Estamos agregando validación aquí para asegurarnos de que no vaya más allá. No va a ninguna parte cerca de la base de datos. No queremos que se convierta en un objeto de dominio si no es válido. Ahora probemos probablemente la más complicada. Entonces te voy a desafiar a que se conformen validadores para la asignación de licencias, que en realidad no es tan diferente. Solo necesitas asegurarte de que el número de días esté presente en Es más de 0. El ID del tipo de hoja no puede ser nulo, tiene que ser mayor que 0 también. Y entonces podrías ampliarte para asegurarte de que el ID tipo de hoja exista en el sistema. Porque si alguien intenta suplantar y Central Valley tipo ID que no existe en nuestra tabla, entonces esa también es una flecha de validación que realmente podemos atrapar antes de intentar comprometer la base de datos. Al llegar a la base de datos, podemos hacer eso para el periodo. Entonces te voy a desafiar a que hagas esa, pero vamos a trabajar juntos en las solicitudes de licencia porque ésta va a tener unas cuantas cosas más en ella. Por lo que una vez más, voy a añadir una nueva carpeta validadores, y luego vamos a empezar con las solicitudes de licencia Crea, validación DTO. ¿ Qué necesitamos validar? Bueno, nuestras fechas necesitan ser fechas válidas. Todavía necesitamos obtener la identificación tipo hoja, así que vamos a hacer eso juntos. Y bueno eso es opcional, así que está bien. Entonces vamos a entrar en esa. Por lo que inicia con nuestra clase crea licencias solicita validador de detalle. Yo lo hago público. Y entonces estoy heredando del validador abstracto relativo a nuestro Crear solicitudes de licencia detalle. Está bien, así que ya escribí parte de la cotización para ti y vamos a pasar por ella. No está terminada porque quiero que hagamos ciertas partes juntas, pero regla para inicio tiene que ser menor que el final. Es ahora vimos que también podríamos usar el valor escalar aquí. Entonces podría haber puesto un entero, pero entonces un entero sería una comparación incompatible con el tiempo. Por lo que podría haber puesto fecha hora, no. Correcto. Tan solo asegúrate de que la fecha de inicio no sea antes de hoy son mayoritariamente antes de hoy, lo cual no es necesariamente el caso, ¿verdad? Por lo que con base en la regla de negocio, es posible que desee comparar en consecuencia, pero esta regla de negocio establece que las fechas de inicio siempre deben ser menores que la fecha de finalización. Y entonces será el mensaje que puedo decir nombre de la propiedad debe ser Antes valor de comparación. Entonces en nuestro detalle de tipo hoja de crear, habíamos codificado duro el 50, codificamos duro el, el uno y el 0 aquí, pero pudimos reemplazarlos fácilmente y hablaba en pársón correctamente. Podríamos reemplazar fácilmente esas áreas con comparación. Dejaré el hardcodificado para nulo, pero solo te estoy mostrando tus opciones, ¿verdad? Entonces estoy viendo que fecha de inicio debe ser antes de NDI lo similitud para la India lo, debe ser mayor que el inicio ordenado y nombre de propiedad y valor de comparación. ¿ Está bien? No, en relación con el tipo de hoja ID, sí dije que nuestra validación podría tomar una serie de formas. Uno, quieres asegurarte de que sea mayor a 0, vale, bien. Y todo lo más importante sin embargo, sería que quieres asegurarte de que exista. Ahora si solo comprobamos si existe, aunque enviaran más de 0, 0 nunca existiría como ID de tipo hoja en la base de datos. Entonces podríamos encadenar es a lo largo porque entonces podríamos desperdiciar esa base de datos llamada simplemente haciendo eso. Por lo que podría decir mayor que. Y luego voy a ver 0. Y entonces también voy a ver que debe existir. Entonces estoy usando lo que ustedes llaman delegado aquí, y voy a borrar todo esto y reescribirlo desde cero que puedan ver exactamente lo que van a decir más paréntesis asíncrona, abierto y cerrado, es un ver, por lo que vamos a esperar, pero luego vamos a definir un delegado. Lo sentimos, no somos que estemos usando, le estamos haciendo saber que es un delegado asíncrono el cual toma algunos parámetros. En este caso, necesitamos el ID, que es el valor. Entonces estamos tomando ese valor como parámetro número 1. Y entonces Tolkien es un token de cancelación como herramienta de parámetros. Y luego estoy usando una flecha Lambda para luego definir algún bloque de objetos o bloque de métodos. Por lo que este bloque de método es donde llevaremos a cabo esa comprobación para ver si existe. Ahora probablemente te estés preguntando, vale, eso significa que necesitamos una base de datos llamada ¿cómo exactamente llamo a la base de datos desde solo un validador? El cool de esto es que nos permite inyectar directamente o dependencias. Muy bien, para que podamos continuar inyectando nuestro repositorio para que sepamos inyectar lo pondrá en el constructor. Podemos usar el punto de control para inicializar el campo. Ya cambié a mis guiones bajos, que es opcional por supuesto. Pero usando eso podemos inset de esta función delegada más acing comprobar la existencia del repositorio leaf I. Entonces dos cosas a tener en cuenta aquí son tres cosas. Una, estamos inyectando el validador nos permite inyectar otras dependencias como nuestros repositorios. Esa es una herramienta. En realidad podemos tener una función personalizada haciendo validación personalizada para que alguien escriba este IN para ello desde cero. Entonces aquí vemos un punto. La mayoría tendría muselina la asíncrona. Eso está bien. Entonces la mayoría asíncrona. Y luego porque estamos usando asíncrona, tenemos que dejar que el modelo delegado, está borrando. Por lo que el delegado es cuándo tomar dos parámetros. ID que representa el mismo ID que estamos validando o el valor que estamos validando. Y tolkien sería representativo del token de cancelación que utilizamos son lambda R0 y luego abrir y cerrar llaves. Entonces dentro de estos tirantes rizados tenemos nuestra lógica. Entonces la primera línea de nuestra lógica es revisar o repositorio si existe el tipo de hoja y luego devolver eso no existe. Está bien, no, esta función que acabo de crear, así que acabo de extender nuestro repositorio genérico para tener un método que devuelva un booleano. Se llama existe y toma int id Así que esto, puedes agregar eso al repositorio genérico y puedes usarlo en cada uno de ellos. Pero el punto es que podemos saber, usar eso para comprobar si existe algo en una tabla en particular. Y en esta situación, es un bonito zapato para comprobar si existe o elif tipo ID. Por lo que debes saber que estás equipado con agarre para manejar esa hoja tipo ID. Te voy a desafiar para que vayas a configurar validadores para la asignación de licencias. Hit pause, tómate unos momentos, configura los validadores Ford asignación de licencias y cualquier otro detalle que no hayamos visto todavía. Y luego cuando vuelvas un más, solo muéstrale otra forma de que podamos refactorizar nuestro código para especie de reducción en la repetición. De acuerdo, así que espero que realmente tomaras el consejo que te fuiste, trataste de hacerte a ti mismo y que tuviste cierta cantidad de éxito. Eso es bueno. Pero entonces quiero mostrarles sólo otro nivel que podemos hacer esto. Entonces cuando estábamos configurando los detalles, como que nos dimos cuenta de que estaría terminando repitiendo nuestras propiedades a través de múltiples detalles. Por ejemplo, el crear hoja tipo D2 y el detalle tipo hoja, en realidad tienen las mismas propiedades bar la fuente. Nadie se basa en el DNI que servimos hasta a través del detalle base. Por lo que las reglas de validación para ambos en realidad serán las mismas excepto quizá la que diga el ID1 al hub de validación para ello. Entonces debido a que uno tiene un ID, uno no, y el validador hasta el momento se han escrito muy fuertemente porque cuando tenemos el detalle de crear tipo hoja, sólo cuatro para crear detalle tipo hoja y actualizaciones, D2 tendría para tener su propio validador. Entonces lo que he hecho es extenderlo un poco. Y esto es lo que llaman desarrollo impulsado por pin. Significa hacer lo que puedas hasta que ya no sea práctico, entonces refactorías, ¿verdad? Entonces cuando estás aplicando estos principios sólidos, a veces no lo ves justo del bate. Pero entonces en cierto momento te das cuenta de que esto se está poniendo tedioso o esto no es práctico, esto no está en consonancia con el principio. Y así refactoriza tu código para sacar el máximo provecho del principal en ese momento. Entonces en este punto, estamos analizando que estamos teniendo las mismas reglas de validación divididas en múltiples archivos, lo cual está bien. O al menos tener múltiples archivos para validaciones está bien. Pero tener las mismas reglas repetidas puede ser peligroso porque entonces si hay que cambiar la regla en una, podríamos cambiarla en una me falta la otra. Conocemos ese riesgo. Entonces lo que he hecho es tener una interfaz que es una obstrucción de nuestros campos. Está bien, así que como dejar tipo detalle que he creado, dejo ese detalle y esto tiene los campos que sabemos que la hoja tab2 necesita tener. Por lo que en el tipo de hoja DTO, he relacionado heredar. Dejo ese detalle. Por lo que estos dos campos son solo las implementaciones de lo que se ha definido en la interfaz. la misma manera en lift IB2, mientras que sí hereda del detalle base, también hereda del detalle tipo elif. Entonces deja que BTO tendría el ID así como las propiedades que vienen de nuestra interfaz. Ahora. De acuerdo, Entonces, así que el siguiente paso es que podemos crear un validador de detalle de tipo I leave, lo que significa que estoy validando contra la interfaz. Por lo que mis reglas ya no se aplican directamente al tipo de hoja DTO. Podrían ser, eso está bien. Pero entonces como vimos, tenemos que tener múltiplo porque tendríamos que tener una hoja completa tab2 en 14, el Create. Por lo que en cambio puedo configurar validaciones contra la obstrucción. Ambos detalles en realidad heredan de la obstrucción. Por lo que estas reglas se aplicarán a ambos. Y luego cuando tengo que personalizarme, tengo mi hoja, ese validador de detalle en el que digo crear hoja. De detalle validador y todo lo que ya sabemos. Pero luego en el constructor simplemente estoy llamando a un método include. Entonces esto es API fluida es que nos estamos siguiendo para tener validadores que se aplican a otras cosas, se aplican a otra clase. Entonces esto realmente se aplica a la interfaz, lo que estoy viendo cuando estoy haciendo este crear validador de detalle tipo hoja, incluye las reglas del validador de detalle de tipo I leave. Y entonces puedo tener mis métodos de disfraz también. Entonces en el detalle de actualización, podría tener el mismo tipo de sintaxis, pero luego son las actualizaciones, lo que significa que también necesito nuestra regla para. Y entonces puedo decir que necesito una regla para los campos ID. Puedo decir punto p. Y luego ver que me está dando todas las propiedades, incluyendo ID porque está en contra de ese tipo. Entonces mi validación para el ID es que no debe ser nulo y debe venir con un nombre de propiedad de mensaje debe estar presente porque por supuesto, cuando estás actualizando, necesitas enviar el ID del registro que estás actualizando, por lo que sí necesitamos esa regla de validación para la actualización y por eso tendría que tener el archivo separado para la actualización. Pero esto es mucho más limpio porque al menos no tenemos que repetir las reglas para el nombre y el tipo o el nombre. Y el valor predeterminado es, lo siento, no tenemos que repetir eso a través de ambos por los datos. Entonces verán que realmente lo hizo ya para la solicitud de licencia y para la asignación de hojas, una vez más, para la solicitud de licencia, tengo dejo solicitudes DTO, y es el mismo código que acabamos de ver cuando las solicitudes de licencia detalle datos válidos con inyección. Y en este caso tenemos que inicializarlo y luego hacemos las reglas. Pero cuando miramos en el Creates leave request detail validator, vemos que tenemos que hacer la inyección. Por lo que aún tenemos que hacer nuestra inyección y tenemos que inicializarla. Y luego pasamos esa inyección al método include porque por supuesto, el validador de detalle de solicitud de IO necesita tener esa inyección. Entonces Kant sí lo llama tenemos que proporcionar ese valor para el constructor. Entonces es sólo esa cadena de margarita, pero creo que esto es mucho más limpio de cualquier manera. Y no tenemos que terminar repitiendo todas estas reglas en todos lados. Por lo que notarás que tanto la creación como la actualización se ven muy similares, excepto el hecho de que la actualización tenga esa regla adicional para el ID. Y solo para completar, tenemos los detalles de asignación de ojos. Yo sí tengo los tirones de ID, las interfaces no mostraron eso. Entonces cualquier cosa que sea común en todos, solo puse eso en la interfaz y luego cualquier otra cosa se puede poner directamente en el detalle según sea necesario y validado en consecuencia. Pero entonces para crear una actualización, esas son todas las cosas que realmente necesitamos. No tenemos que necesariamente fin de semana sentido de la regla de validación tipo de comentarios de solicitud tal vez limiten la longitud. No necesariamente tenemos que hacer nada por cancelado. Una vez más, solo te estoy dando los lineamientos. Tus reglas y requisitos de negocio pueden ser diferentes, pero configuras tus validaciones según sea necesario. Por lo que nuestra licencia de actualización solicita detalle hereda de la base, y dejo solicitudes detalle. No tenemos que hacer eso para la lista porque no estamos validando la lista. Tampoco estamos validando el detalle de detalle, pero eso crea definitivamente tiene que heredar. Y luego la aprobaciÃ