0% encontró este documento útil (0 votos)
76 vistas217 páginas

Book - APIs Con CLean Architecture y .NET Core N3

Cargado por

VLADO DOTNET
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
76 vistas217 páginas

Book - APIs Con CLean Architecture y .NET Core N3

Cargado por

VLADO DOTNET
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 217

VladoDotNet – Ingeniería de software y Diseño

Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Diseño API con


Clean Architecture, .Net
Core Blazor y Swagger

35 vídeos para los laboratorios ¡Aplica ya!, paso a paso.


paso
Plus: Incluye prácticas con SOLID y 9 patrones de diseño.
diseño

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

PRÁCTICO CURSO DE API REST


CON CLEAN ARCHITECTURE
Incluye:

❖ Introducción a Arquitecturas, Principios y Patrone,


❖ Prácticas con SOLID, cíclos de vida .Net Core C# y Asincronísmo,
❖ Inyección de dependencia fondo,
❖ Reglas de Negocio,
❖ DTO, Mapper,
❖ Seguridad JWT,
❖ Documentación OpenAPI
❖ Deployment On Premises y Cloud Azure
❖ Cuestionarios de repaso
❖ Descarga de Código a solicitud del usuario

¡Visualiza cada etapa!

¡Sin enredos!
Sigue tu desarrollo Paso a paso
haciendo uso de UML,
diagramas de secuencia

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Checklist Paso a paso

Ten a mano la secuencia de


cada proceso de programación,
configuraciones y código.

Conoce y aplica Swagger

Aplica conceptos fundamentales del


diseño API con Swagger OpenApi, para
atender los requerimientos del cliente y
los usuarios.

Seguridad: Aprenda a autenticar y


autorizar usuarios de su API para el
acceso a recursos protegidos.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Construye con Clean Architecture

Aprende ya a diseñar proyectos con Clean Architecture,


.Net Core, Blazor y C#.

Domina unos de los patrones de diseño y desarrollo de


software más populares por su claridad y código
sostenible.

Deployment API

Despliegue On Premises

Configure e instalé su API en el servidor


local IIS de Microsoft.

Aprenda a desplegar sus aplicaciones y


realice las configuraciones necesarias en
el servidor.

Despliegue OnCloud

Publique sus API 's en la nube, con la


plataforma Azure y sus servicios tipo
SaaS.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

PRESENTACIÓN
1. Una revisión a las Arquitecturas de software
2. Código limpio, principios y estilos
3. Patrones de diseño
4. Patrón CQRS: Segregación de responsabilidades
5. La Calidad y el patrón Clean Architecture
6. Creación de la estructura de un proyecto con el patrón Clean Architecture

7. SOLID, Ciclos de vida, Asincronismo, Abstracción, DI y otros conceptos


8. Modelo y enlace de datos
9. El patrón Repository
10. Abstracción de servicios
11. Implementando los DTO’s
12. Mapper

13. Refactoring
14. Reglas de negocio
15. CRUD API
16. Excepciones
17. Filtros
18. El estándar Open API con Swagger
19. Implementado documentación API

20. Credenciales
21. Token JWT
22. Esquema de Autorización Bearer y creación de usuarios API
23. Aplique el Patrón Unit Of Work (UoW)

24. On Premises
25. On Cloud Azure Devops

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

1. Practica con 5 principios SOLID, C# Console.


2. 9 Patrones populares, C# Console.
3. Practicando con Ciclos de vida.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

ESTRUCTURA DEL PROYECTO


Los vídeo tutoriales se desarrollan con base en la estructura del proyecto Escuela Norte
aplicando la arquitectura limpia tipo Onion Clean Architecture así:

Capa Carpeta/Servicios
Proyecto: Api.EscuelaNorte
Presentación
Tipo: .NET Core API

Proyecto: Core.EscuelaNorte
Core/Dominio
Tipo: Class Library .NET Standard.

Proyecto: Infraestructura.EscuelaNorte
Infraestructura
Tipo: Class Library .NET Standard.

Proyecto: Testing.EscuelaNorte
Testing Tipo: Carpeta de soluciones
Carpetas: xUnitTest.EscuelaNorte; IntegracionTest.EscuelaNorte

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Vídeos Aplican

01. APIs CON C.A. - Creando la base de datos., 56 ● Intro a Arquitecturas, Principios y
02. APIs CON C.A. - Creando el proyecto, 60 Patrones
03. APIs CON C.A. - El Modelo, 99 ● Inyección de dependencia,
04. APIs CON C.A. - El Repositorio y DI, 99 ● Reglas de Negocio,
05. APIs Con C.A. - Dto Y Mapeo I, 106
● DTO,
06. APIs Con C.A. - Dto Y Mapeo II, 106
● Mapper,
07. APIs CON C.A. - Refactoring DbContext, 109
08. APIs CON C.A. - CRUD en el repositorio, 117 ● Filtros
09. APIs CON C.A. - Capa de negocio I, 119 ● Seguridad JWT,
10 APIs CON C.A. - Excepciones I, 133 ● Docs API con Swagger
11. APIs CON C.A. - Excepciones y Filtros II, 133 ● Deployment On Premises IIS y Cloud
12. APIs CON C.A. - Excepciones y filtros III, 133 Azure
13. APIs CON C.A. – Filtros: Servicio de filtrado, 140
14. APIs CON C.A. - Documentación API I, 158
15. APIs CON C.A. - Documentación API II, 158
16. APIs CON C.A. - Documentación API III, 158
17. APIs CON C.A. – JWT I, 178
18. APIs CON C.A. – JWT II, 178
19. APIs CON C.A. - Usuarios I, 192
20. APIs CON C.A. - Usuarios II, 192
21. APIs CON C.A. - Usuarios III, 192
22. APIs CON C.A. - Usuarios IV, 192
23. APIs CON C.A. - Usuarios V, 192
24. APIs CON C.A. - Repositorio Genérico I, 198
25. APIs CON C.A. - Repositorio Genérico UoW - II, 200
26. APIs CON C.A. - Deploy On Premises, 213
27. APIs CON C.A. - Deploy OnCloud I, 213
28. APIs CON C.A. - Deploy OnCloud II, 213
29 Caso #1: Principio SOLID SRP, 215
30 Caso #2: Principio SOLID OCP, 215
31 Caso #3: Principio SOLID LSP, 215
32 Caso #3: Principio SOLID LSP variante, 215
33 Caso #4: Principio SOLID ISP, 215
34 Caso #5: Principio SOLID IoD, 215
35: Prácticando con los ciclos de vida., 216

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Beneficios Línea curricular

● Nivel: Avanzado ● Algoritmia


● Acceso: De por vida ● Programación Orientada a Objetos
● Idioma: Español ● C# , MVC
● Certificado académico (previa evaluación): Sí ● Fundamentos de .NET Core y Blazor
● Certificado de asistencia: Sí ● Fundamentos de API REST
● Descargar material: Sí (ver curso nivel intermedio)
● Descargar código: Sí, a solicitud
● Actualizaciones: Actualizable
● Actualizado: 15/11/2022

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

CONTENIDO

PRÁCTICO CURSO DE API REST CON CLEAN ARCHITECTURE 2

¡Visualiza cada etapa! 2


Checklist Paso a paso 3
Conoce y aplica Swagger 3
Construye con Clean Architecture 4
Despliegue On Premises 4
Despliegue OnCloud 4

PRESENTACIÓN 5

PARTE I: ARQUITECTURAS, PRINCIPIOS Y PATRONES 5


PARTE II: SOLID, DTO’S, MAPPING Y ABSTRACCIÓN 5
PARTE III: REGLAS DE NEGOCIO, EXCEPCIONES, OPENAPI 5
PARTE IV: SEGURIDAD JWT, PATRÓN UOW 5
PARTE V: DEPLOYMENT API 5
PARTE VI: PRACTICANDO CON SOLID Y PATRONES DE DISEÑO 6

ESTRUCTURA DEL PROYECTO 7

ESTRUCTURA GENERAL 7
ÍNDICE DE VÍDEOS TUTORIALES: LABORATORIOS ¡APLICA YA! 8
BENEFICIOS Y LÍNEA CURRICULAR 9

CONTENIDO 10
PARTE I: ARQUITECTURAS, PRINCIPIOS Y PATRONES 18

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

LECCIÓN: EL CONCEPTO ARQUITECTURA DE SOFTWARE 18


LA METÁFORA DEL CARGUERO 19
ARQUITECTURA DE SOFTWARE 20
PROCESO BÁSICO DE UNA ARQUITECTURA DE CALIDAD 21
Código limpio – Buenas prácticas 21
Principios de diseño 23
ESTILOS DE ARQUITECTURA 24
Estilo N niveles 25
Web-Cola-Trabajo 25
Microservicios 26
Basada en eventos 26
Big Data 27
MODELAMIENTO DE LA ARQUITECTURA 27
Diseño de alto nivel 27
Patrones de diseño 28
QUÉ SON LOS PATRONES DE DISEÑO 29
BUILDER 30
PROTOTYPE, CLONACIÓN 31
TIPOS FACTORY, SIMPLY FACTORY 32
ABSTRACT FACTORY 33
SINGLETON 34
Variante lazy 35
Variante not lazy 36
STRATEGY, PATRÓN DE COMPORTAMIENTO 39
PATRÓN UNIT OF WORK (UOW) 42
CQRS: SEGREGACIÓN DE RESPONSABILIDADES 43
Arquitectura tradicional 44
Enfoque CQRS: dos modelos 44
Implemente CQRS cuando… 45
REPASE SUS CONOCIMIENTOS 46
VERIFIQUE SU COMPRENSIÓN 47
COMPRUEBE SU APRENDIZAJE 48
LECCIÓN: LA CALIDAD Y CLEAN ARCHITECTURE 49
IMPORTANCIA DE LA ARQUITECTURA Y LA CALIDAD 49
El Martillo dorado o Ley del martillo 49
CALIDAD VS ARQUITECTURA 50
ARQUITECTURA VS CALIDAD 51
ENTONCES ¿POR QUÉ CLEAN ARCHITECTURE? 51
BENEFICIOS DE C.A 52
¿CUÁNDO UTILIZAR C.A? 53
COMPRUEBE SUS CONOCIMIENTOS 54
VERIFIQUE SU COMPRENSIÓN 54
LECCIÓN: ANTES DE INICIAR… HERRAMIENTAS Y CONFIGURACIONES 55
INSTALANDO EL ADMINISTRADOR DE IIS DESDE WINDOWS 55
LECCIÓN NUESTRA BASE DE DATOS MODELO CON SQL SERVER 57

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

LABORATORIO ¡APLICA YA! 57


VÍDEO N° 1 57
01. APIs CON C.A. - Creando la base de datos. 57
LABORATORIO ¡APLICA YA! 58
Aplicando C.A. al Proyecto modelo ‘Escuela Norte’ 58
Proyectos base 59
UML: Diagrama de secuencia 60
CHECK LIST, Paso a paso 60
VÍDEO N° 2 61
02. APIs CON C.A. - Creando el proyecto 61
ADVERTENCIA 61

PARTE II: ABSTRACCIÓN, PRACTICANDO SON SOLID, REPOSITORY, DTO’S 62

LECCIÓN SOLID, ABSTRACCIÓN, DI Y OTROS CONCEPTOS CLAVE 62


PRACTICANDO CON LOS PRINCIPIOS SOLID 64
N° 1: Single Responsibility Principle (SRP) 64
N° 2: Open/Closed Principle (OCP) 64
N° 3: Liskov (Bárbara Liskov) Substitution Principle (LSP): 64
N° 4: Interface Segregation Principle (ISP) 65
N° 5: Control Inversion Principle (IoC): 65
LABORATORIOS ¡APLICA YA! PRACTIANDO CON SOLID 65
Caso de estudio principio #1, SOLID SRP 65
Caso de estudio principio #2, SOLID OCP 70
Caso de estudio principio #3, SOLID LSP 73
PLUS : CLASES ABSTRACTAS 76
Variante caso principio LSP 78
Caso de estudio principio #4, SOLID ISP 79
Caso de estudio principio #5, SOLID IoC 83
VÍDEO: practicando con SOLID 87
INVERSIÓN DE CONTROL IOC E INYECCIÓN DI 88
TÉCNICAS PARA DI 90
Inserción de constructores 90
Inserción de acción con el atributo FromServices 90
Acceso a la configuración desde un controlador 91
INYECTANDO DEPENDENCIA —DI 91
PLUS 94
ASINCRONISMO: CICLO DE VIDA DE UN SERVICIO 95
Transitorio 95
Con ámbito 95
Duración de un servicio Singleton 95
Los beneficios del asincronismo 96
Practicando con los ciclos de vida .Net Core 96
LABORATORIO ¡APLICA YA! 96

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

VÍDEO: Comportamiento de los ciclos de vida 96


Material adjunto 97
UML: Diagrama de secuencia 98
CHECK LIST, Paso a paso 100
VÍDEO N° 3 y 4 100
03. APIs CON C.A. - El Modelo 100
04. APIs CON C.A. - El Repositorio y DI 100
LECCIÓN EL MAPEO Y LOS DTO 101
LOS DTO 101
HACIENDO USO DE LOS DTO 103
MAPPING 104
LABORATORIO ¡APLICA YA! 105
UML: DIAGRAMA DE SECUENCIA 105
CHECK LIST, PASO A PASO 106
VÍDEOS N° 5 Y 6 107
05. APIs Con C.A. - Dto Y Mapeo I 107
06. APIs Con C.A. - Dto Y Mapeo II 107
REAFIRME SUS CONOCIMIENTOS 108

PARTE III: REGLAS DE NEGOCIO, EXCEPCIONES, OPENAPI 109

LECCIÓN REFACTORIZANDO EL PROYECTO 109


¿REFACTORIZAR CUÁNDO? 109
LABORATORIO ¡APLICA YA! 109
CHECK LIST, PASO A PASO 109
VÍDEO N° 7 110
07. APIs CON C.A. - Refactoring DbContext 110
LECCIÓN FUNDAMENTOS DE LA REGLAS DE NEGOCIO CAPA BLL 111
¿QUÉ SON LAS REGLAS DE NEGOCIO? 113
DEFINIENDO REGLAS DE NEGOCIO 113
COMPOSICIÓN DE UNA REGLA DE NEGOCIO 113
LABORATORIO ¡APLICA YA! 114
DIAGRAMA DE SECUENCIA SIN UNA CAPA DE NEGOCIO 114
AGREGANDO REGLAS DE NEGOCIO Y CRITERIOS DE ACEPTACIÓN 114
DIAGRAMA DE SECUENCIA INCLUYENDO CAPA DE SERVICIOS BLL. 116
UML: DIAGRAMA DE SECUENCIA 116
PARTE I: COMPLETANDO EL CRUD DEL REPOSITORIO 118
CHECK LIST, PASO A PASO 118
VÍDEO N° 8 118
08. APIs CON C.A. - CRUD en el repositorio 118
PARTES II: IMPLEMENTANDO LA REGLA DE NEGOCIO N° 1. 119
CHECK LIST, PASO A PASO 119
VÍDEO N° 9 120
09. APIs CON C.A. - Capa de negocio I 120

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

VERIFIQUE SU APRENDIZAJE 120


LECCIÓN CONTROL DE EXCEPCIONES 121
CÓDIGOS DE ESTADO 121
Respuestas informativas (100-103) 121
Respuestas satisfactorias (200-299) 122
Redirecciones (300 – 308) 123
Errores de cliente (400 – 451) 124
Errores de servidor (500 – 511) 126
CONTROL PERSONALIZADO DE EXCEPCIONES 127
FILTRO DE ERRORES: IEXCEPTIONFILTER 127
RESPONSES LEGIBLES 128
PLUS 129
TIPOS DE REGISTRO 130
Registro en el ActionResult 130
Registro por controlador 131
Globalizado 131
UML: DIAGRAMA DE SECUENCIA 132
LABORATORIO ¡APLICA YA! 133
CHECK LIST, PASO A PASO 133
VÍDEO N° 10 , 11 Y 12 134
10 APIs CON C.A. - Excepciones I 134
11. APIs CON C.A. - Excepciones y Filtros II 134
12. APIs CON C.A. - Excepciones y filtros III 134
VERIFIQUE SU COMPRENSIÓN 135
LECCIÓN FILTROS: CONSULTAS POR PARÁMETROS 136
¿POR QUÉ EL FILTRADO? 136
FILTROS EN UN CONTROLADOR 136
FILTROS PERSONALIZADOS 136
LISTA DE MÉTODOS PARA FILTRADO 136
PLUS: REQUERIMIENTOS DEL CLIENTE 138
BINDING DE DATOS 138
SECUENCIA DE EJECUCIÓN DE UN FILTRO 139
CHECK LIST, PASO A PASO 140
VÍDEO N° 13 141
13. APIs CON C.A. – Filtros: Servicio de filtrado 141
COMPRUEBE SUS CONOCIMIENTOS 142
LECCIÓN EL ESTÁNDAR OPENAPI 143
LOS ENDPOINT 143
PLUS 145
OPENAPI: OAS OPEN API SPECIFICATION 145
LAS PROPIEDADES 145
DIAGRAMA DE LA ESTRUCTURA OPENAPI 146
ESTRUCTURA BÁSICA DE UNA API CON OPENAPI 147
CAMPO DE RUTAS 148
CAMPO DE COMPONENTES: RESUMEN 149

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

OBJETO PATHS 151


CAMPO DE WEBHOOKS, CALLBACK 151
SOLICITUDES Y RESPUESTAS 153
DOCUMENTACIÓN AUTOMATIZADA 155
PLUS 155
DOCUMENTACIÓN EN .NET CORE 155
LECCIÓN DOCUMENTACIÓN API EN .NET CORE Y SWAGGER 157
SALIENDO A PRODUCCIÓN 157
PLUS 157
Aspecto final de la documentación básica API en .NET Core 158
LABORATORIO ¡APLICA YA! 158
IMPLEMENTANDO LA DOCUMENTACIÓN CON SWAGGER 158
CHECK LIST, PASO A PASO 158
VÍDEOS N° 14, 15 Y 16 159
14. APIs CON C.A. - Documentación API I 159
15. APIs CON C.A. - Documentación API II 159
16. APIs CON C.A. - Documentación API III 159
REAFIRME SUS CONOCIMIENTOS 160

PARTE IV: SEGURIDAD JWT, UOW, DEPLOYING 161

LECCIÓN LA SEGURIDAD DE LA APIS CON JWT 161


¿QUÉ ES AUTENTICAR? 161
¿QUÉ ES UN TOKEN? 162
JSON WEB TOKEN 163
¿POR QUÉ JWT? 163
LAS PARTES O ESTRUCTURA DE UN TOKEN 164
Header 164
Payloads, Carga Útil 165
Verify Signature, Firma 166
Error 401 168
Base64Url 169
LA SOLICITUD Y RESPUESTA CON JWT 170
UML: Diagrama de secuencia 171
Plus: contrarrestando la vulnerabilidad 173
LABORATORIO ¡APLICA YA! 173
UML: Diagrama de secuencia 174
UML: Diagrama de secuencia 175
UML: Diagrama de secuencia 176
UML: Diagrama de secuencia 177
CHECK LIST, Paso a paso 178
VÍDEO N° 17 179
17. APIs CON C.A. – JWT I 179
VÍDEO N° 18 179

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

18. APIs CON C.A. – JWT II 179


LECCIÓN AUTENTICACIÓN Y AUTORIZACIÓN PARA CREACIÓN DE NUEVOS USUARIOS DESDE LA API 180
LABORATORIO I ¡APLICA YA! 180
FLUJO DE DATOS CON SWAGGER 181
CHECK LIST, Paso a paso 184
LABORATORIO II ¡APLICA YA! 186
CHECK LIST, Paso a paso 186
COMPRUEBE SUS CONOCIMIENTOS 187
LECCIÓN CONFIGURANDO LA AUTORIZACIÓN: TOKEN BEARER CON SWAGGER 188
ESQUEMAS DE SEGURIDAD OPENAPI 188
CONFIGURACIÓN PARA EL ESQUEMA BEARER (PORTADOR) 189
LABORATORIO III ¡APLICA YA! 190
Habilitar los servicios de autenticación Swagger 190
CHECK LIST, Paso a paso 193
VÍDEO N° 19 – 23 193
19. APIs CON C.A. - Usuarios I 193
20. APIs CON C.A. - Usuarios II 193
21. APIs CON C.A. - Usuarios III 193
22. APIs CON C.A. - Usuarios IV 193
23. APIs CON C.A. - Usuarios V 193
LECCIÓN ¡NOT DRY!, REPOSITORIOS Y PATRONES 194
EL PRINCIPIO DRY 194
REPOSITORIOS 195
Inconvenientes a resolver con un repositorio 196
Ventajas de un repositorio 196
TIPOS DE REPOSITORIOS 196
Repositorios por entidades 196
Repositorio genérico 197
PATRÓN UNIT OF WORK (UOW) 197
LABORATORIO ¡APLICA YA! 198
VÍDEO N° 24 199
24. APIs CON C.A. - Repositorio Genérico I 199
LABORATORIO ¡APLICA YA! 200
VÍDEO N° 25 201
25. APIs CON C.A. - Repositorio Genérico UoW - II 201
COMPRUEBE SUS CONOCIMIENTOS 202
DESPLIEGUE DE LA API: ON PREMISE Y AZURE 203
AZURE 203
ESCENARIOS DE DESARROLLO 206
AZURE APP SERVICE 207
ACCESO A AZURE DESDE .NET 207
ALTERNATIVA PARA PUBLICACIÓN DE UNA APLICACIÓN 208
On premises deployment con .Net Core 208
LABORATORIO ¡APLICA YA! 209
Parte I: On Premises deployment 209

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

VÍDEO N° 26 214
26. APIs CON C.A. - Deploy On Premises 214
LABORATORIO ¡APLICA YA! 214
Parte II: OnCloud deployement 214
VÍDEO N° 27, 28 214
27. APIs CON C.A. - Deploy OnCloud I 214
28. APIs CON C.A. - Deploy OnCloud II 214

SIGUIENTE PASO NIVEL AVANZADO II 215

SINGLE PAGES APPLICATION: ¡DISEÑO DE UNA TIENDA CON BLAZOR! 215

APÉNDICE A 216

VÍDEOS: Practicando con SOLID, C# 216


Vídeo 29 Caso #1: Principio SOLID SRP 216
Vídeo 30 Caso #2: Principio SOLID OCP 216
Vídeo 31 Caso #3: Principio SOLID LSP 216
Vídeo 32 Caso #3: Principio SOLID LSP variante Vídeo 33 Caso #4: Principio SOLID ISP 216
Vídeo 34 Caso #5: Principio SOLID IoC 216

APÉNDICE B 217

Vídeo 35: Prácticando con los ciclos de vida. 217

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño
PARTE
Diseño. Series desde cero. https://vladodotnet.wordpress.com/
1
PARTE I: ARQUITECTURAS,
PRINCIPIOS Y PATRONES

Después de esta lección aprenderá:

1. Entender el concepto de Arquitectura de Software y temas relacionados


2. Reconocer las características de una arquitectura de calidad.
3. Identificar los principios de diseño clave
4. Conocer los estilos de arquitectura básicos
5. Comprender qué es un patrón de diseño
6. Identificar los principales patrones de diseño de software y sus ventajas
7. Comprender qué es Clean Architecture
8. Reconocer el patrón CORS
El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

La metáfora del carguero

Plus

Como parte del aprendizaje es común hacer uso de metáforas. Para tener una buena visual de conceptos como
Arquitecturas, Modelos, Patrones, entre otros, haremos uso a través de los siguientes apartados de la metáfora del
carguero.

Seguramente conoce los cargueros que arriban a un puerto. Estos son


grandes barcos que
ue transportan mercancía a nivel internacional. Como se
observa en la imagen, transportan los productos y servicios haciendo uso
de Contenedores.. Los contenedores o cajas metálicas de colores, son
grandes estructuras metálicas previamente selladas desde su puerto de
origen, para conservar y proteger los productos de la intemperie y los
maleantes.

Aplicando la parábola, tendremos los siguientes equivalentes al proceso de


transporte de un carguero:

1. CONTENEDOR: Paquete de software abstraído del sistema operativo y su entorno tecnológico.


Contienen…

2. EL EMBALAJE: Empaque de Productos y servicios: Empaques generalmente en cajas grande de madera,


cartón o material con aislamiento.

Hay docenas de estas cajas dentro del contenedor.

Para nuestro estudio, equival


equivalen
en a todos los productos de software almacenados en cada
embalaje y a su vez dentro de los contenedores, organizados por categorías. Es decir: el software
se adapta al ESTÁNDAR del contenedor. Por ejemplo: Módulos de software Microservicios,
clasificados en sus embalajes y contenedores por categorías, tipos especializados.

3. EL CRUCERO: Encargado de transportar, administrar y gestionar


muchos contenedores.
En sistemas de información equivale a los gestores de contenedores como
Docker.
4. ADMINISTRADOR EN EL PUERTO DESTINO: Gestiona, administra
todos los cargueros, mejorando sus operaciones, optimizando el viaje y
descarga.

En TIC 's equivale a un arreglo de clusters administrado por una aplicación globalizada.
Ejemplo:Kubernetes.

¡El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Arquitectura de software
Como observó en la parábola anterior, u
unn arquitecto de software se encarga de encajar cada
uno de los componentes,, módulos, proyectos de una solución, aplicación o sistema de
información respetando siempre las buenas prácticas y estándares y de manera optimizada.

Así, la arquitectura de software se encarga de crear los planos que rigen el diseño del software.
Es por esto que programador no es necesariamente un arquitecto de software.

Arquitecturas deficientes

Existen varias características propias de un mal diseño arquitectónico de software. Dentro de las más significativas
encontraremos:

1. Integraciones concentradas en la elegancia pero no resuelven los problemas funcionales.


funcionales
2. Herramientas obsoletas con versioness muy antiguas y sin soporte actual. Aplicar una arquitectura de
software eficiente implica sobrecostos en los proyectos.
3. Migración y refactorización manual de sistemas antiguos,
uos, generando inconsistencias que desgastan
el talento humano en una tarea titánica y desagradable.
4. Parche y parches para intentar acoplar una aplicación a los estándares arquitectónicos
implementados por la organización.
5. Sincronización de fuentes de datos de modo manual.

¡El Aprendizaje Hecho Fácil!

Arquitecturas eficientes

Dentro de las características más importantes encontraremos:

1. Se implementan siguiendo metodologías de desarrollo.


2. Estrategias de implementación orientada al target y estrategia corporativa.
3. Herramientas acertadas para la automatización e integración.
4. Las reglas de negocio deben regir el diseño de interfaces y fuentes de datos, no al contrario.
5. Establecer permanentes técnicas de pruebas
6. Buscar siempre el desacople incluso de frameworks
7. Se puede actualizar y modifi
modificar con rapidez. Es de fácil lectura.

¡El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Proceso básico de una arquitectura de calidad


Como parte de las etapas que constituyen un arquitectura limpia, encontramos los siguientes
procesos:

Código limpio – Buenas prácticas


Significa aplicar las convenciones y estándares internacionales. Aplicar principios del diseño de
software como SOLID, entre otros, facilitan diseño de código con alta calidad:

Como prácticas generales tenemos para generar un código limpio:


1. Estándares y convenciones internacionales.
2. Pruebas: Verificar que las pruebas unitarias y otras sean factibles de aplicar.
3. Principios SOLID: Haga auditoria permanente de su aplicación.
4. Bajo acoplamiento: Se caracteriza por el desuso de la palabra new. Así, las
abstracciones no dependen de los detalles sino todo lo contrario.
Por ejemplo: la manera de obtener los datos de la base de datos debe ser transparente
para las interfaces y demás módulos. Es decir, estas desconocen los detalles cuando se
ejecutan queries o transacciones.
5. Bajo acoplamiento al hardware: conocido como ’Adhesión estática’.
Las dependencias de código con la máquina limitan las pruebas y el mantenimiento de
software. Por ejemplo, el uso de la función-método DateTime.Now en C#, es un ejemplo
típico de acoplamiento al dominio del reloj del hardware. Además la dependencia a la
máquina afecta nuevas instancias. Una alternativa para impedir esto es que cada
instancia maneje esa función de reloj. Otra solución elegante es crear un mecanismo de
abstracción como lo aprenderá en este curso. 1 El tipo a usar podría ser DateTimeOffset
para zonas horarias distintas. Algo así:

Ejemplo:
// La interfaz
public interface IRelojMaquina
{
DateTimeOffset Now { get; }
}
//Implementando…
public class RelojMaquina : IRelojMaquina
{
public DateTimeOffset Now { get { return System.DateTimeOffset.Now; } }
}

1
Ver parte II, SOLID… ABSTRACCIÓN

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

¡No se preocupe!

El código anterior puede ser nuevo para usted.

El objetivo de este curso es dejar claros los conceptos a medida que va practicando.
Todo irá siendo más claro con el paso de las lecciones.

¡El Aprendizaje Hecho Fácil!

6. Manejo eficiente de los constructores:: Modelar como equipo de desarrollo clases que
se instancian en estados válidos. Eso significa tener una plantilla de programadores con
buenas bases en POO (Programación Orientada a Objetos).
7. DI (Inyección de Dependencias): pasar las dependencias al método constructor como
un parámetro. Esto elimina llamadas estáticas por el uso de la cláusula new. Así, evitamos
el acoplamiento.
8. Contenedores de servicios
servicios: La IoC o Inversión de Control
ontrol permite que grandes
aplicaciones compuestas por varios proyectos no sufran dependencias, gracias a que
cada servicio se declara de modo independiente par paraa cada proyecto. Así cada uno hace
uso de lo que necesita.
9. Respetar el Principio de segregación LS LS: Es dejar de depender de lo que no se utiliza.
No debe implementarse código en, por ejemplo, los controladores API para acceder por
instanciación a la capa de datos o DbContext ni de los repositorios.. Haga uso de la
abstracción que se especializa en su implementación encargada de la tarea para acceder
a los repositorios. En sus controladores se realizará la instanciación pero a los servicios
manejados por los mecanismos de abstracción.
10. IEnumerable: Este tipo de ActionResult es idóneo para ser incluido en el mecanismo de
abstracción. Úselo cada vez que vaya a generar una lista de datos.

Ejemplo:
//Mecanismo de abstracción
public interface IEstudianteRe
IEstudianteRepo
{
IEnumerable<Estudiante>
<Estudiante> ListaEstudiantes( );
}

Recuerde registrar el servicio en el Contenedor de servicios que para el presente curso


será el archivo Program.cs

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Como ejemplo, tenemos:


builder.Services.AddScoped< IEstudianteRepo, estudianteRepo>( );

Nota: Addscope nos indica que se creará una instancia independiente por cada
solicitud. Esto es uno a uno, 1:1

Por otra parte, con Singleton se podrán crear instancias para ser utilizadas en todas las
solicitudes de ese tipo. Esto es uno a muchos 1:M, una instancia para muchas
solicitudes. Esto lo estudiaremos en lecciones posteriores y lo usaremos en los
laboratorios ¡Aplica ya!.

11. Lógica empresarial: NO debe involucrarla en los controladores. Estos deben estar
dedicados a sus propios asuntos (SoC, o separación de preocupaciones). Use las
interfaces e implemente los servicios o aplique otras técnicas de implementación.
12. POO: nos ayuda a crear bases sólidas en la arquitectura de software al diseñar
complementos flexibles además de crear modelos de dominio robustos y estables.
Es ya obligado hacer uso de este paradigma de programación. Utilice a fondo sus cuatro
pilares, a saber:
- Abstracción.
- Encapsulamiento.
- Polimorfismo.
- Herencia.

Principios de diseño
Usted debe tener claro esto:
Las soluciones de software se deben diseñar y crear con el mantenimiento en mente.

Los principios ayudan a decidir la arquitectura indicada. Dentro de la lista de principios


encontramos:
1. SoC, Separación de intereses: separe las tareas especializadas que realizará el software
acorde a sus funciones. Separe la lógica del negocio de la interfaz de usuario y la
infraestructura. Cada una en capas o proyectos independientes como lo aplicaremos en
los laboratorios con Clean Architecture.
2. Encapsulamiento: el aislamiento de las capas en un diseño de gran calidad, debe
permitir aislamiento y autonomía. Ajustar la implementación interna sin afectar el
entorno es una característica sobresaliente del concepto de microservicios. Acceder a
nuestras clases encapsuladas será posible solo mediante mecanismos de interfaces. Las
modificaciones y evolución del diseño interno y encapsulado será fluido y respetando los
contratos públicos, como verá en lecciones posteriores.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

3. IoC, inversión de dependencia: ¡Siempre desarrolle con la dirección de dependencia


hacia la abstracción!, es decir, nunca hacia los detalles de implementación. Se ejemplifica
en la PARTE II de este curso.
4. Principio de dependencia explícita: Significa que las clases no pueden funcionar
solamente si existen componentes globalizados. Esto se puede observar en clases que
usan constructores y solicitan elementos adicionales pero en la realidad requieren otros
más.
Explicado de otra manera: Las firmas dentro de las clases que aplican este principio,
deben solicitar explícitamente sea mediante parámetros en los constructores, los
objetos necesarios para su funcionalidad.
Este principio obliga a evitar que cualquier clase que diseñemos esté libre de
dependencias implícitas, debido a que este tipo de modelamiento genera una fuerte
adhesión y acoplamiento, violando varios principios de buenas prácticas y dificultando la
fase de pruebas o testing: Evite que una clase acceda a otra para desarrollar sus
actividades. Nuevamente para evitar esto, haremos uso de las interfaces públicas.
5. Responsabilidad única: Indicado en la lista de principios SOLID, señala que un objeto
debe cumplir con una y solo una responsabilidad. Esto obliga a establecer que debe
existir entonces y de modo recíproco una y solo una razón para ser modificado. ¡Y esto
es distinto al proceso de actualizar el objeto!
Aplicar este principio nos permite generar aplicaciones con mínimo acoplamiento y gran
flexibilidad modular.
La conexión lógica de un proyecto así, es la base de los microservicios. O en otras
palabras: ¡los microservicios deben tener una y solo una responsabilidad! Porque no se
deberían agregar nuevas funcionalidades o responsabilidad a uno ya existente. Se deben
crear entonces nuevos microservicios si se respeta este principio.
6. ¡DRY!: No repetir la misma función o procedimiento en otros lugares. Aplicar este
principio evita incoherencias e inconsistencias.
La duplicidad se evita creando clases especializadas que centralizan la operación
duplicada. Además agregando la funcionalidad a firmas de una interfaz, obligará a que
los componentes hagan uso de esta para evitar la práctica ineficiente de duplicar.

Existen otros principios que se dejan como para de la investigación del estudiante
autodidacta.

2
Estilos de arquitectura
Los estilos arquitectónicos para el diseño de software conforman un equipo con características
muy especiales que no requieren de tecnologías concretas. Tenemos:

2
Microsoft, extracto.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Estilo N niveles

Fuente: Microsoft.

Ideal para aplicaciones empresariales. Toda dependencia se administra haciendo uso de capas
como veremos en los laboratorios ¡Aplica ya! con la implementación de Clean Architecture. Es
muy usada en soluciones de infraestructura como IaaS (Infrastructures as a Service) que
ofrece servicios de informática en la nube para procesos esenciales, almacenamiento y redes
entre otros. Observe las capas de servicios Web, mensajería, Data y servicios remotos
independientes. Las capas más externas pueden llamar a las capas debajo de estas.

Web-Cola-Trabajo

Fuente: Microsoft.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Se utiliza para tareas de uso intensivo de la CPU, operaciones de larga duración, solicitudes
HTTP controladas por un front-end web. Ideal para modelos cloud tipo PaaS (Platform as a
Service que proveen hardware, software e infraestructura

Microservicios

Fuente: Microsoft.

Se conforma por servicios pequeños y especializados e independientes que implementan una


función empresarial y de mucho uso en aplicaciones de dominio complejo, como sería el
sector bancario. Cada microservicio se comunica a través de contratos API. Este estilo de
arquitectura brinda mucha independencia entre los equipos de desarrollo, facilitando la cultura
Devops, gran velocidad de entregas, rápida innovación y en general una arquitectura muy
resistente.

Basada en eventos

Fuente: Microsoft.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Ideal para productores que publican eventos-suscripciones y los clientes se suscriben, todos
independientes entre sí. Utilizado para software especializado en el manejo de grandes
volúmenes de datos muy generalizados en soluciones tipo IoT3 de uso masivo.

Big Data

Fuente: Microsoft.

Gestión y procesamiento de grandes volúmenes de datos con procesamiento en paralelo para


su análisis e informes. El manejo de datos masivos relacionados con la navegación de millones
de internautas, es un ejemplo de Big Data

Modelamiento de la arquitectura
Antes de escribir código, es fundamental identificar cada uno de los conceptos expuestos hasta
aquí. Con .Net será posible crear modelos para reconocer comportamientos del software,
identificar patrones repetitivos, analizar cambios, reduciendo la ambigüedad y las
interpretaciones, apoyando al equipo de trabajo para obtener una visual clara del diseño a
emprender.

La arquitectura de un sistema se divide en:


1. Área de diseño de alto nivel.
2. Área de patrones de diseño.

4
Diseño de alto nivel
Se describen los componentes y las interacciones entre componentes principales del sistema y
el modo en que interactúan entre sí para lograr los objetivos del diseño.

3
Internet de las cosas.
4
Microsoft.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Se comienza por describir los requisitos:


1. Identificar las características principales de las necesidades de los usuarios.
2. A continuación, puede analizar las secuencias de interacciones de los casos de uso
principales y,
3. Posteriormente, consolidar las secuencias en un diseño de componentes.

Por ejemplo, como parte de las necesidades del usuario tenemos las reglas de negocio.
negocio

Como verá en las lecciones siguientes,


corresponden a restricciones o políticas
internas de la organización.
organización Haciendo uso
de herramientas para modelado en .Net, se
pueden escribir en estilo comentarios
comentari
como se observa en la imagen.

Fuente: Microsoft.

Patrones de diseño
Seguidamente se deben elegir los patrones arquitectónicos.
Estos nos ayudan a explicar en detalle la implementación de los estilos arquitectónicos
Esto implica las tecnologías y elementos arquitectónicos básicos del sistema. Tenemos entre
otros:
1. DDD – Domain Driven Design: El diseño basado en dominios se usa para dominios
complejos donde la arquitectura por capas facilita el trabajo
trabajo.

Arquitecturas Onion

Este tipo de patrón de diseño para implementar la arquitectura de una aplicación o sistema de
información TIC’s, es le utilizado durante el curso.

¡El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

2. MVC – Model – View – Controller: Ideal para el desarrollo enfocado en interfaces de


usuario. Aunque para sistemas con mucha lógica empresarial no es tan indicado.

Finalmente como parte de la arquitectura, se define el modelo de datos relacionados con los
componentes e interfaces. En este punto es ideal el uso de los diagramas de clases que
facilitan la descripción de la información a través de cada componente y su almacenamiento. En
.Net por ejemplo, se hace uso de Entity Framework (EF) con todas sus utilidades para el
modelamiento de acceso y gestión de los datos (Model, SQL Server, IIS, etc.).

En cualquier caso, debe empezar por concebir y codificar las características principales de los
requisitos y el diseño. Ocúpese de los detalles en posteriores iteraciones del proyecto.

Definidos de manera sencilla: PLANOS ESTRUCTURALES DE CÓDIGO Y LÓGICA.

De seguro como programador de software ha tenido experiencias con aplicaciones o proyectos


que tienden a convertirse en código espagueti. Ese tipo de diseño es un problema potencial a
la hora de implementarlo especialmente en sistemas escalables de alto crecimiento.

Los patrones aunque son ‘plantillas’ no pueden simplemente replicarse o ser usados de manera
indiscriminada. Su utilidad básica es guiarnos en el diseño ideal y óptimo de la lógica, los
algoritmos y los servicios dependiendo del tipo de sistema, políticas de negocio y
requerimientos del usuario. Por ejemplo: un sistema de información financiero requerirá
módulos, arquitectura, algoritmos y rutinas distintas al sistema de información de una fábrica
que produce infinidad de componentes a escala, y además los agrupa acorde a los pedidos de
sus clientes multinacionales.

Existen varios libros muy populares dentro de la comunicad de desarrolladores, dedicados a este
tema. Por ejemplo, uno de los libros de ingeniería de software más populares Design Patterns
de los GoF (Gang of Four) o banda de los 4 ingenieros, define un total de 23 patrones que nos
orientan a aplicar los principios del diseño de software como reutilización de código,
extensibilidad o el cambio y evolución del software. Echemos una mirada y resumen a los
siguientes patrones de diseño y sus categorías:

Creacionales
● Abstract Factory: Familias de objetos de productos.
● Builder: Cómo se crea un objeto compuesto.
● Factory Method: Subclase de un objeto instanciado.
● Prototype: clase de un objeto que es instanciado.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

● Singleton: Instanciación de un objeto único.

Estructurales
● Adapter: Interfaz de un objeto.
● Bridge: Implementación de un objeto.
● Composite: Estructura y composición de un objeto.
● Decorator: Responsabilidades de un objeto sin subclases.
● Facade: Interfaz de un subsistema.
● Flyweight: Coste de almacenamiento en objetos.
● Proxy: Como un objeto es accedido. Su localización.

Comportamiento
● Chain of Responsibility: Objeto rellenado en una petición.
● Command: Cuándo y cómo una petición es rellenada.
● Interpreter: Gramática e interpretación de un lenguaje.
● Iterator: Como un elemento agregado es accedido, transversalmente.
● Mediator: Cómo y qué objetos interactúan entre sí.
● Memento: Qué información privada se almacena fuera del objeto y cuando.
● Observer: Número de objetos que se relacionan, y cómo mantener actualizadas las
relaciones.
● State: Estado de un objeto.
● Strategy: Un algoritmo.
● Template Method: Pasos para un algoritmo.
● Visitor: Operaciones que pueden ser aplicadas a un objeto sin cambiar su clase.

Ahora revisemos algunos:

Builder
Facilita la construcción paso a paso de objetos haciendo uso de Constructores sin necesidad de
invocar los métodos innecesarios para el diseño de los objetos. Así, los constructores realizan la
misma tarea pero de forma distinta. Aquí se establece una clase directora o Base (clase
Abstract en .Net) que organiza la secuencia ordenada de pasos necesarios para el objeto o
servicio solicitado. Todo lo anterior evita el uso excesivo de parámetros en los constructores. Por
supuesto en la medida que existan nuevos parámetros se deberá refactorizar o especializar las
clases derivadas.

Ventajas:
1. Ideal para diseños con procedimientos similares que requieren pocas variaciones.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

2. Reúso de código para variantes del producto.


3. Aislar código complejo de la capa de negocio.

Desventajas:
1. La exigencia de nuevas clases aumenta la complejidad del modelo

Aplique Builder

Como ejemplo, este patrón lo encontrará como parte de la implementación UoW o repositorio genérico
genéric
más adelante en este curso. Su funcionalidad centraliza en una clase abstracta propiedades genéricas
como se observa en el código siguiente:

namespace Core.EscuelaNorte.Entidades
{
public abstract class EntidadBase
{
public int ID { get
get; set; }
}
}

Tome un screen y envíe sus respuestas a vuelta de correo para retroalimentación

Prototype, clonación
Los objetos que admiten ser clonados se conocen como prototipos.
La metáfora de la división celular es un ejemplo de este patrón.

Este patrón de diseño facilita copiar o duplicar objetos con código independiente de las clases.
En la realidad intentar clonar objetos impli
implica
ca terminar conociendo sus miembros privados u
ocultos. Este impedimento se supera con el patrón Prototype al declarar una interfaz común que
contendrá un método universal clonar()
clonar().. En el caso de .Net Core, se implementa llamando a la
interfaz IClonable. Esta
sta interfaz facilitará la copia incluso de los campos encapsulados de objetos
de la misma clase en dos clasificaciones de este patrón: clonación superficial y clonación
profunda.

Se recomienda utilizar este patrón cuando el código no depende de clases concretas


oncretas a clonar.

Ventajas:
1. Clonación sin necesidad de crear objetos desde cero.
2. Facilita la creación de objetos complejos.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Desventajas:
1. Se puede presentar referencia cruzada.

Tipos Factory, Simply Factory


Los patrones de factoría tienen varias clasificaciones. Miremos el Simply Factory:
Se fundamentan en una superclase creadora implementando una interfaz común y
permitiendo separa el código de construcción del código que lo usa, facilitando extender los
componentes internos. Se utiliza en escenarios donde se desconocen las dependencias y tipos.
Así, este patrón reduce considerablemente el uso de los recursos del sistema por el
alto reuso de los objetos creados. La interfaz común definirá las firmas con base en los
productos finales.

Con este patrón creamos una ‘fábrica de servicios’ centralizada. Esto permitirá dos cosas muy
importantes:

1. Refactorización.
2. Evitar el acoplamiento.

Por ejemplo, la cláusula New genera acoplamiento de por vida. Como se observa en el siguiente
código. Por supuesto se entiende que el servicio está fuertemente desacoplado por carencia de
los mecanismos de desacople como veremos más adelante:

var ServicioMatriculasNorte = new ServicioMatriculaNorte();

Observa ahora el siguiente ejemplo en C#, el lenguaje a utilizar en todos los laboratorios:

var servicioMatriculasNorte = new Servicio();

//PERO POR NUEVOS REQUERIMIENTOS TENDREMOS QUE PRESTAR MÁS SERVICIOS


var servicioMatriculasSur = new Servicio();
var servicioMailsCumpleaños = new Servicio();

//ENTONCES ENCAPSULAMOS LA CREACIÓN DE OBJETOS EN UN SOLO MÉTODO: FACTORY SIMPLY.


public Static FactorySimply
public Static Servicio NewServicio()
{
return new Servicio("ConectString",
new servicioMatriculasNorte,
new servicioMatriculasSur
new servicioMailsCumpleaños)
}

//INSTANCIANDO EL SERVICIO APLICANDO EL PATRÓN FACTORY SIMPLY:


void servicioEN = FactorySimply.NewServicio();

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Ventajas:
1. Disminuye el acoplamiento.
2. Aplica el principio de responsabilidad única.5
3. Incluir nuevos tipos sin afectar el código existente.

Desventajas:
1. Multitud de subclases.

Aplique Simply Factory

Tendrá la oportunidad de aplicar este patrón al implementar interfaces para la prestación y


centralización de servicios, especialmente para el manejo de las reglas de negocio. Observe un ejemplo
del código que usted podrá diseñar en el paso a paso de los laboratorios. El código diseña una interfaz
que implementará el patrón UoW para el manejo centralizado de los repositorios de su proyecto. Esto
implica desacoplamiento y el principio SOLID de responsabilidad única:

namespace Core.EscuelaNorte.Interfaces
{
public interface IUoW : IDisposable
{
//RELACIÓN DE REPOSITORIO GENÉRICOS...
IRepoGenerico<TblEstudiante> EstudianteRepoGenerico { get;
; }

//Firma genérica para registro de cambios en repositorios...


Task RegistrarCambiosAsync();

}
}

Tome un screen y envíe sus respuestas a vuelta de correo para retroalimentación

Abstract Factory
Este patrón se caracteriza por generar objetos de categorías similares sin especificación de sus
clases abstractas.

Ventajas:
1. Compatibilidad de objetos.
2. Disminución de acoplamiento de código y dependencias.

5
Los principios SOLID se tratan más adelante.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

3. El principio de responsabilidad única facilita su mantenimiento.


4. Facilidad de insertar nuevas variantes.

Desventajas:
El código puede ser más complejo por la gran variedad de interfaces.

Singleton
Facilita una única instanciación de clase con un punto de acceso global donde los clientes
trabajarán con el mismo objeto de modo transparente. Lo anterior implica que se deshabilita la
alternativa de crear objetos de otras maneras… Utiliza el objeto creado o crea uno nuevo,
nuevo es
decir: nada puede
de reemplazar la instancia actual en caché
caché,, por lo que se deben crear
constructores de clase de tipo privado.

En el caso de .Net C#, el uso de la palabra reservada new solo puede ser utilizada una sola vez.
En aplicaciones que hacen uso de la DI (inyecció
(inyecciónn de dependencia) y abstracción, Singleton es
ideal para inicializar el acceso a los repositorios así:

Aplique Singleton

Observe la mecánica al implementar este patrón en los laboratorio del curso:


Se hace uso del encapsulamiento. Posteriormente se aplica DI (Inyección de dependencia)
dependencia a través del
constructor. Esto nuevamente implica desacoplamiento y el principio SOLID de responsabilidad única:

public class EstudianteController : ControllerBase


{
// A través de la capa de Servicios o BLL...
private readonly IEstudianteBLL _estuBLL;

//PARA AUTOMAPEO... DI
private readonly IMapper _mapeo;

public EstudianteController
EstudianteController(
IMapper mapeo,
IEstudianteBLL estudiante)
{
_estuBLL = estudiante;
_mapeo = mapeo;

}
Tome un screen y envíe sus respuestas a vuelta de correo para retroalimentación

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

¡Pierda cuidado!

El código anterior puede ser nuevo para usted.

Hara uso extenso de este patrón en todos los laboratorios.


Todo irá siendo más claro con el paso de las lecciones.

¡El Aprendizaje Hecho Fácil!

Variantes Singleton

Características comunes: Para todas la variante encontraremos los siguientes aspectos comunes:

 Uno y solo un constructor privado.


 Una y solo una variable de referencia a la instancia encapsulada.
 Un miembro de tipo estático que permita el get de la instancia.
 No se requieren clases selladas.

El Aprendizaje Hecho Fácil!

Variante lazy
Recuerde que la instanciación solo se da por solicitud directa. La primera referencia al miembro
estático ocurre en el método estático Instance, y las clases anidadas tienen acceso a los
miembros privados de la clase primaria. A continuación el algoritmo original de esta variante:

//ALTERNATIVA 1
public sealed class clsSingletonLazy1
{
private clsSingletonLazy1
clsSingletonLazy1()
{
}

public static clsSingletonLazy1 Instance { get { return Nested.instance; } }

private class Nested


{
static Nested()
{
}

internal static readonly clsSingletonLazy1 instance = new


clsSingletonLazy1();

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

}
}

//ALTERNATIVA 2
public sealed class clsSingletonLazy2
{
private static readonly SingletonLazy2<clsSingletonLazy2> oLazy =
new oLazy<clsSingletonLazy2>(() => new clsSingletonLazy2());

public static clsSingletonLazy2 Instance { get { return oLazy.Value; } }

private clsSingletonLazy2(){}
}

//ALTERNATIVA 3: No hay bloqueos y asegura subprocesos


public sealed class Singleton
{
private static readonly SingletonOK instance = new Singleton();

//El compilador JIT no lo marca hasta inicializar


static SingletonOK()
{
}

private SingletonOK() <- Constructor


{
//Aquí acceso a miembros privados
}

public static SingletonOK Instance


{
get
{
return instance;
}
}
}

Variante not lazy


No olvidemos que los constructores estáticos se declaran para ser usados sólo con la creación
de la instancia de la clase o si se hace referencia a un miembro estático. Dado que esta
verificación para el tipo que se está construyendo debe ejecutarse pase lo que pase, será más
rápido que agregar una verificación adicional como en los ejemplos anteriores.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

El patrón a utilizar

Singletón, variante No Lazy será el patrón utilizado en los laboratorios de este curso para el desacople y la
implementación del mecanismo de abstracción
abstracción.
El Aprendizaje Hecho Fácil!

El uso de propiedades y campos deben declararse estáticos. Todo lo anterior permite que el
servicio basado en este patrón se ejecute una sola vez de por vida. Así, el constructor y servicio
de uno de nuestro endpoint se declara
declararía así:

private static readonly IEstudianteRepo _estudianteRepo; <-Interfaz


Interfaz por inyección de
dependencia (DI)

public EstudianteController(IEstudianteRepo
IEstudianteRepo estudianteRepo)
{ _estudianteRepo = estudianteRepo; } <
<- Mecanismos para acceso a encapsulados;
Constructor

//El servicio
Singleton.Instance.MiembrosClase
MiembrosClase() //Implementación tipo No Lazy:
La instancia se crea al ejecutar la aplicación utilícese o no.

Asegurando los subprocesos


Esta variante es ideal para el aseguramiento de subprocesos. Asegura que sólo un subproceso
creará una instancia. Desafortunadamente, el rendimiento se ve afectado ya que se adquiere un
bloqueo cada vez que se solicita la instancia. Los objetos deben ser privados
rivados para la clase en la
que se utilizan. Esto ayuda a que la escritura de aplicaciones seguras para subprocesos sea
significativamente más fácil. Observe el siguiente código:

public sealed class clsSingletonProceso


{
private static clsSingletonProceso instance = null;
private static readonly object oBloqueo = new object();

clsSingletonProceso()
{
}

public static clsSingletonProceso Instance


{
get
{
lock (oBloqueo)
{
if (instance == null)

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

{
instance = new clsSingletonProceso();
}
return instance;
}
}
}
}

El anterior algoritmo se ha catalogado como de gran rendimiento cuando se hace uso del
bloqueo (look) debido a que hace uso de un solo bloque y verificación inmediata.

Singleton para muchos servicios y una dependencia


Cuando encontramos necesidad de implementar muchos servicios y para modelos multicapa
haciendo uso de una sola dependencia, el patrón Singleton es idóneo. Por ejemplo observe que
la dependencia1 generada por abstracción de la Interfaz que facilita los servicios, es reusada en
muchos servicios (1,2,3):

public ConstructorServicio1 (
Interfaz1 dependencia1,
Interfaz2 dependencia2,
Interfaz3 dependencia3)
{
...
}
public ConstructorServicio2 (
Interfaz1 dependencia1,
Interfaz2 dependencia2)
{
...
}
public ConstructorServicio3 (
Interfaz1 dependencia1,
IDependencia4 dependencia4)
{
...
}

En términos generales para el patrón Singleton encontramos:

Ventajas:
1. Control de las variables globalizadas.
2. Seguridad al tener una sola instancia.
3. Inicialización de objetos solo en el arranque de la solicitud.

Desventajas:
1. Se viola el principio de responsabilidad.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

2. Difícil manejo de hilos.


3. Dificulta las pruebas unitarias para clases privadas y sobreescritura de métodos estáticos.

Strategy, patrón de comportamiento


Es idóneo para procesos que varían mucho en su propia categorización, encapsulándolos de
los que permanecen constantes. Permite establecer una clase especializada
llamada contexto encargada de delegar la tarea a un objeto llamado objeto estrategia. En este
patrón es el cliente el encargado de seleccionar y pasar la estrategia que necesite. La
clase contexto interactúa con los objetos estrategia a través de una interfaz genérica compuesta
de un único método que llamara la estrategia solicitada.

Este patrón es ideal para tablas que tienen varios campos con muchas variantes o alternativas,
similares a los combos de selección. Así, permite refactorizar algoritmos con muchos
condicionales extensos o switches para dichos campos, ubicando la lógica en clases
especializadas pero con una sola interfaz. Analicemos el siguiente caso:

Caso
En la Escuela Norte (laboratorio de este curso) , los estudiantes realizan muchos tipos de
solicitudes como certificado de notas, certificado de asistencia, formas de pago, cambio de
jornada (nocturna, diurna), clases personalizadas o a distancia, entre otras.

//EL ALGORITMO QUE NORMALMENTE VIENE AL CASO:


//Existe en nuestra DBS una entidad "Solicitud"
//compuesta por un campo con muchas variantes.

//Decidimos declarar una clase especializada


//en atender todas las MODALIDADES de solicitud:

public class GestionSolicitudes


{
public bool ValidarSolicitudes(Solicitud oSolicitud)
{
switch (oSolicitud.TipoSolicitud)
{
case TipoSolicitud.CambioJornada:
return GestionarCambioJornada(oSolicitud);

case TipoSolicitud.CertificadoAsistencia:
return GestionarCertificadoAsistencia(oSolicitud);

case TipoSolicitud.ClasesPersonalizadas:
return GestionarClasesPersonalizadas(oSolicitud);

case TipoSolicitud.CertificadoNotas:
return GestionaCertificadoNotas(oSolicitud);
.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

.
.
n cases

default:
return false;
}
}

//AQUÍ LOS MÉTODOS POR SOLICITUD


private bool GestionarCambioJornada(Solicitud oSolicitud)
{
/*Procedimientos de gestión*/
return true;
}
private bool GestionarCertificadoAsistencia(Solicitud oSolicitud)
{
/*Procedimientos de gestión*/
return true;
}
private bool GestionarClasesPersonalizadas(Solicitud oSolicitud)
{
/*Procedimientos de gestión*/
return true;
}
private bool GestionaCertificadoNotas(Solicitud oSolicitud)
{
/*Procedimientos de gestión*/
return true;
}

Si los tipos de solicitudes continúan creciendo por igual crecerá la cantidad de métodos para
gestionar cada solicitud. Tener una clase con muchos métodos es un indicador para atender la
refactorización de la clase. Ahora apliquemos el patrón Strategy:

// PASO 1: DECLARAMOS LA INTERFAZ

public Interface IStrategySolicitudes


{
bool ValidarSolicitudes(Solicitud oSolicitud);
}

// PASO 2: DI (Dependency Inyection) por constructor:

public class ValidarSolicitudesStrategy


{
private readonly IStrategySolicitudes _context;
public ValidarSolicitudesStrategy(IStrategySolicitudes parValidar)
{
_context= parValidar;
}

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

public bool ValidarSolicitudes


ValidarSolicitudes(Solicitud oSolicitud)
{
return _context.ValidarSolicitudes
ValidarSolicitudes(oSolicitud);
}
}

// PASO 3: IMPLEMENTAMOS LOS MÉTODOS ESTRATEGY QUE ATIENDEN


// SU PROPIA ESTRATEGIA PARA SERVICIO DE ValidarSolicitudes:

public class GestionarCambioJornada : IStrategySolicitudes


{
public bool ValidarSolicitudes
ValidarSolicitudes(Solicitud oSolicitud)
{
//Aquí los procesos de validación y gestión
//Un Ejemplo:

VerificarMatriculasJornadas
VerificarMatriculasJornadas(oSolicitud.IDMatricula);
}
}

public class GestionaCertificadoNotas


GestionaCertificadoNotas: IStrategySolicitudes
{
public bool ValidarSolicitudes
ValidarSolicitudes(Solicitud oSolicitud)
{
//Aquí los procesos de validación y gestión
//Ejemplo:
VerificarEstadoNotas(oSolicitud.IDEstudiante);
(oSolicitud.IDEstudiante);
}
}

//OBSERVA QUE NUESTRA CLASE CONTEXT (ValidarSolicitudesStrategy)


//no requerirá más ajustes cuando se presenten
//nuevos tipos de solicitudes.

//Agregaremos nuevas clases especializadas en su gestión.

Recomendaciones generales

1. Para acceder a la misma instancia con un mismo parámetro, se recomienda el uso del patrón Factory
Method.
2. Se sugiere la implementación Lazy para cargar la instancia solo en el momento que se requiera.
3. Dependiendo del tipo de aplicación se pueden omitir con constructores estáticos para incrementar el
rendimiento debido a que el compil
compilador JIT realizará una y solo una verificación.
El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Otros patrones

Encontrará otro tipo de patrones de acuerdo a su clasificación. Estos se dejan como parte de su investigación. Por
ejemplo:

1. Patrones estructurales:
Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy.
2. Patrones de comportamiento:
Chain of Responsibility, Command, Iterator, Mediator, Memento, Observer, State, Strategy, Template
Method, Visitor.
El Aprendizaje Hecho Fácil!

Patrón Unit of Work (UoW)


La unidad clase de trabajo tiene un propósito: asegurarse que cuando utilice varios repositorios,
compartan un único contexto ((DBContext) de base de datos.

Aplicando UoW

Este patrón se explicará y aplicará ámpliamente en la lección


lección:
“¡Not
¡Not DRY!, repositorio y patrón UoWUoW” más adelante.

¡El Aprendizaje Hecho Fácil!

De esa manera, cuando una UoW está completa, puede llamar al método transaccional en esa
instancia del contexto y estar seguro de que todos los cambios relacionados se coordinarán.
Todo lo que la clase necesita es un método especializado para la transacción y una propiedad
para cada repositorio.6

En resumen: todas las transacciones (CRUD) en una unidad UoW se realizan en una sola
transacción haciendo uso de una única instancia del DbContext como se observa en la
siguiente imagen.

6
Microsoft

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Aplique este patrón en lecciones porsteriores como indica la nota anterior.

CQRS: Segregación de responsabilidades


Command Query Responsibility Segregation

Existen en la actualidad varios enfoques para el manejo e implementación de un middleware


entre la fuente de datos subyacente y la aplicación y cliente. Lograr un CRUD eficiente forma
parte del proceso de aplicar ingeniería de software y arquitecturas apropiadas. Todo enfoque
depende del tipo de sistema, los requerimientos, el alcance, la escalabilidad, entre otros.

Segregar responsabilidades en el acceso a los datos implica hacer uso del correcto enfoque para
el manejo de las consultas o queries y los comandos. CQRS facilita la separación de
responsabilidades o preocupaciones tanto en la lectura o consulta como en el registro y
actualización de los datos, maximizando el rendimiento, seguridad y
escalabilidad controlando los posibles conflictos en el dominio de la aplicación.

Es: cada método debe ser un comando que realice una acción, o debe ser una consulta que
recupere datos … pero no ambos. O es un método void o no. Por ejemplo, un método Post
agergaría nuevos estudiantes a la lista (comando). Y si además retorna el total de estudiantes a
la fecha, una vez actualizado el nuevo registro (count), entonces estamos ejecutando tambien
una consulta en el mismo método. Esto es lo contrario de CQSR.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Arquitectura tradicional
Tradicionalmente el diseño de una apl aplicación utiliza el Model o representación esquemática de
la fuente de datos para todas las operaciones relacionadas en un CRUD. El mapeo y los DTO se
pueden tornar complejos en sistemas de información más avanzados y escalables, incluso en las
tareas de validación y lógica de negocio. Lo complejo termina impactando los indicadores de
gestión, eficiencia y eficacia. Así, el enfoque tradicional en sistemas más avanzados impacta el
rendimiento por el incremento en la complcomplejidad
ejidad y carga de datos con las consultas
consu y la capa de
datos, además del control de la seguridad, roles, permisos, tokens, etc.

Enfoque CQRS: dos modelos


En lugar de tener un modelo unificado, debe introducir dos: uno para lecturas (queries) y otro
para escrituras (comandos). Al separar lectura y escritura implementando varios Models se
logran superar los inconvenientes de la arquitectura tradicional. Esto implica o cubre:

1. Operaciones de lectura <


<- Queries, consultas
2. Operaciones de actualización
actualización, transacciones <- Comandos

El enfoque de las consultas (queries) va dirigido a devolver un DTO sin encapsulamientos.


encapsul Es
decir: NO modifica la fuente de datos subyacente.

Por otro lado, el enfoque de los comandos se concentra en las tareas no en los datos y se
procesan asincrónicamente. No es m modificar
odificar o actualizar los datos, es gestionar la tarea base.
Esto facilita aislar los datos de lectura y los datos de escritura. Esto implica la posibilidad de
tener “dos bases de datos” y esquemas: Una tipo documento y otra relacional por supuesto
debidamente
ente sincronizadas. Gran parte de la lógica empresarial formará parte del lado de la
escritura (comandos).

Scaffold

El patrón CQRS no permite el uso de Scaffold 7 para la generación automatizada del modelo.

El Aprendizaje Hecho Fácil!

7
Scaffold: Framework o utilidad para generar código de modo automatizado. Usado especialmente con MVC.
MVC

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

CQRS y los datos

Separar los datos de escritura y de lectura “… los datos de lectura pueden estar obsoletos. El almacén de modelos
de lectura debe actualizarse para reflejar los cambios en el almacén de modelos de escritura y puede ser difícil
8
detectar cuándo un usuario ha emitido una solicitud basada en datos de lectura obsoletos.”

El Aprendizaje Hecho Fácil!

Implemente CQRS cuando… 9


1. Existan Dominios colaborativos donde muchos usuarios acceden a los mismos datos en
paralelo.
2. Interfaces de usuario basadas en tareas donde los usuarios son guiados a través de un
proceso complejo como una serie de pasos o con modelos de dominio complejos.
3. Escenarios en los que el rendimiento de las lecturas de datos debe ajustarse por
separado del rendimiento d de las escrituras de datos, especialmente cuando el número
de lecturas es mucho mayor que el número de escrituras
escrituras.
4. Escenarios en los que un equipo de desarrolladores puede centrarse en el modelo de
dominio complejo que forma parte del modelo de escritura y otro equipo puede
centrarse en el modelo de lectura y las interfaces de usuario.
5. Escenarios en los que se espera que el sistema evolucione con el tiempo y pueda
contener varias versiones del modelo, o en los que las reglas de negocio cambien
regularmente.
6. Integración con otros sistemas
sistemas,, especialmente en combinación con el abastecimiento
de eventos,, donde la falla temporal de un subsistema no debería afectar la
disponibilidad de los demás.

Este patrón no se recomienda cuando:


● El dominio o las reglas de nego
negocio son simples.
● Una interfaz de usuario simple al estilo CRUD y operaciones de acceso a datos son
suficientes.

8
Microsoft.
9
Microsoft

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Repase sus conocimientos

Marque las respuesta correctas:

Acorde a la metáfora del carguero, los microservicios forman parte de un


contenedor.

Un gran gestor de contenedores es Docker.

El arquitecto de software se encarga de validar el código.

Un programador necesariamente debe ser arquitecto de software.

Una arquitectura eficiente se basa en una interfaz elegante.

La migración
ión y refactorización de sistemas antiguos debe realizarse de
modo manual para minimizar tiempo y costos.

Un buen manejo de arquitecturas orienta el diseño a la estrategia


organizacional.

Es más práctico crear estándares locales para codificar.

El alto acoplamiento implica dejar de usar la palabra new.

La adhesión estática implica dependencia de código con la máquina.

Un contenedor de servicios permite aplicar el principio de IoC.

Dejar de depender de lo que no se usa se conoce como principio


princ de
segregación.

La lógica empresarial involucra a los controladores en .Net.

El mantenimiento de software es el objetivo central al aplicar los


principios de diseño.

Aplicar la POO, encapsulamiento, nos ayuda a separar la lógica de


negocio de la interfaz.

Tome un screen y envíe sus respuestas a vuelta de correo para retroalimentación

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Verifique su comprensión

Relacione los elementos:

1. Factory simply.
2. Strategy.
3. CQRS.
4. Builder.
5. DDD.
6. Singleton

Muchos servicios y para modelos multicapa haciendo uso de


una sola dependencia. Una sola instancia
instancia.

Es el diseño basado en dominios. Se usa para dominios


complejos donde la arquitectura por capas facilita el
trabajo.

los constructores realizan la misma tarea pero de forma distinta. Aquí se


establece Aquí Aquí se establece una clase directora (clase

Un objeto debe cumplir con una y solo una


responsabilidad.

No repetir la misma función o procedimiento en otros


lugares. Aplicar este principio evita incoherencias e
inconsistencias

Se fundamentan en una superclase creadora implementando


una interfaz común y permitiendo separa el código de
construcción del código que lo usa

Tome un screen y envíe sus rrespuestas


espuestas a vuelta de correo para retroalimentación

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Compruebe su aprendizaje

Relacione los elementos:


7. Encapsulamiento.
8. DRY.
9. IoC.
10. Soc.
11. Responsabilidad única.

Implica separar la lógica de negocio de la interfaz

Es muy usado en diseño de microservicios

¡Siempre desarrolle con la dirección de dependencia hacia la


abstracción!, es decir, nunca hacia los detalles de
implementación.

Un objeto debe cumplir con una y solo una


responsabilidad.

No repetir la misma función o procedimiento en otros


lugares. Aplicar este principio evita incoherencias e
inconsistencias

Tome un screen y envíe sus respuestas a vuelta de correo para retroalimentación

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Después de esta lección aprenderá a:

1. Comprender la importancia y el impacto de una arquitectura en el desarrollo de software de alta calidad.


2. Conocer las bases de Clean Architecture y cuándo utilizarla.
3. Definir e implementar la estructura arquitectónica del proyecto Escuela Norte aplicando Clean
Architecture.
4. Establecer las referencias entre las capas de un proyecto C.A.

El Aprendizaje Hecho Fácil!

Importancia de la arquitectura y la calidad


En diversidad de cursos dictados en instituciones universitarias y online me enfrascaba con los
estudiantes en la discusión de ‘casarnos’ con un par de tecnologías como las panaceas del
inmenso recorrido de un programador de software. Intenté ayudarles a comprender
omprender el
trasfondo.

Veinte años después muchos de ellos han estado incluyendo en su portafolio de herramientas,
más tecnologías necesarias para ser competitivos.

El Martillo dorado o Ley del martillo


Representa nuestra desviación de la realidad para querer resolver problemas o traer soluciones
con nuestra forma de ver la realidad usando la misma herramienta una y otra vez.

El Dr. Maslow hace mención del concepto (1966) comentando:


“Supongo que es tentador pensar que, si la única herramienta que tienes es un martillo, puedes
tratar cualquier cosa como si fuera un clavo.”

En otras palabras: Nos limitamos dañinamente al intentar solucionar todo con


un solo un enfoque.
Por tal motivo se aclara que existen docenas de arquitecturas, tecnologías y
paradigmas
adigmas para diseñar software. Todo depende de la necesidades y
variables que cada situación amerite. Así, con un martillo debe ser complicado
apretar una tuerca.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Clean Architecture es un estupendo paradigma para afinar nuestras Buenas Prácticas.


Bienvenido a su aprendizaje…. sin convertirla en el Martillo de Maslow.

Calidad vs Arquitectura
Debe saber que existen millones de programadores en todos los continentes, escribiendo miles
de líneas de código, o en el campo de batalla atendiendo incidente
incidentes,
s, requerimientos y mejoras.
Desde el preescolar hasta la universidad, niños, adolescentes y adultos profesionales o
aficionados disfrutan desarrollando sus aplicaciones, con o sin estándares, con o sin calidad…. y
¡funcionan!

Pero en general, el software de calidad, especialmente en terrenos corporativos es otro asunto,


aunque por igual nuestra imagen profesional está en juego. Crear software con altos estándares
y convenciones a la medida de los requerimientos del cliente, en el menor tiempo posible y conco
el mínimo de errores no es tarea tan fácil como lo hacen ver los aficionados. Para lograrlo se han
desarrollado disciplinas basadas en la ciencia como la ingeniería de software, patrones de
diseño, arquitecturas y estándares.

Arquitectura vs Calidad

El objetivo de la arquitectura de software es minimizar los recursos


humanos necesarios para construir y mantener el sistema requerido.

La medida de la calidad del diseño es simplemente la medida del


esfuerzo requerido para satisfacer las necesidades del cliente. Si
ese esfuerzo es bajo y se mantiene bajo durante toda la vida útil del
sistema, el diseño es bueno. Si ese esfuerzo crece con cada nueva
eso.10
versión, el diseño es malo. Es tan simple como eso
El Aprendizaje Hecho Fácil!

10
Martin C. Robert.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Arquitectura vs Calidad
De acuerdo a amplios estudios corporativos, la productividad se hace más baja con cada nueva
versión del mismo producto como se observa en la imagen.

El doctor Martin indica: “… Desde el punto de vista de


los desarrolladores, esto es tremendamente
amente frustrante,
porque todos están trabajando duro.

Nadie ha disminuido su esfuerzo. Y, sin embargo, a


pesar de toda su heroicidad, horas extras y dedicación,
simplemente ya no están haciendo mucho de nada.

Todo su esfuerzo se ha desviado de las características y ahora se consumen con la gestión del
desorden. Su trabajo, tal como es, ha cambiado a mover el desorden de un lugar a otro,
otro y al
siguiente, y al siguiente, para que puedan agregar una pequeña característica más escasa…” 11

Entonces ¿por qué Clean Architecture?


Las diferentes etapas por las que ha pasado el diseño o arquitectura de software en décadas, ha
sufrido un permanente inconveniente: el acoplamiento o dependencia entre componentes y
capas.

Además se ha dejado relegado el modelo de negocio al permitir que este —el


el core—
core sufra
fuertes acoplamientos en todo el sistema. Esto por
supuesto ha impactado la escalabilidad y los cambios
inevitables han llevado a tener una gráfica
fica de
productividad negativa como se muestra en la anterior
ilustración.

Clean Architecture permite separar la lógica de la


aplicación y la lógica empresarial (reglas de negocio) que
corresponden al core o dominio, de la implementación o
los detalles que corresponden a las capas externas.

Así, las áreas internas son


on independientes
y desconocen los detalles de las las capas externas.

11
Ibid.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

La comunicación con estas es limpia gracias a conceptos como la abstracción, los principios
SOLID entre otros el IoC —Inversión de Dependencia y la especialización de tareas en el
sitio que corresponde.

En este curso crearemos proyectos que representen cada una de las capas del modelo C.A.
En resumen tenemos inicialmente las siguientes:

1. Capa de dominio: debe representar todas las clases Core núcleo del negocio que
representan:
a. Las entidades de dominio,
b. Los DTOs,
c. Enumeraciones,
d. Excepciones,
e. Interfaces ,
f. Las reglas de negocio o servicios entre otras, dependiendo de las necesidades de
la organización o proyectos TI.

2. Capa de aplicación: En esta capa encontramos:


a. Casos de uso, Validaciones,
b. Autorizaciones, políticas.
c. Patrón CQRS.

3. Capa de persistencia: todo lo relacionado con nuestra de fuente de datos subyacente


como la conexión y gestión de la base de datos.

4. Capa de infraestructura: Todo lo relacionado con:


a. Interfaces y servicios externos independientes como Web services externos,
Microservicios, despacho mailing.
Esta capa puede agruparse con la capa de persistencia por estar en el mismo nivel.

5. Capa de presentación: El frontend del software o tipo de proyecto seleccionado, que


para efectos del curso será la API.

Beneficios de C.A
De acuerdo a Robert C. Martin encontramos los siguientes beneficios:

1. Independencia de la Interfaz de usuario (UI).


2. Independencia de cualquier almacén de datos subyacente: La lógica de la aplicación
NO va en nuestras bases de datos. Esto genera una gran dependencia al momento de
migrar a otras fuentes de datos.
3. Facilidad a la hora de realizar testing.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

4. Independencia de los frameworks: Gracias a que nuestro Business Core es independiente


como capa en nuestro proyecto.
5. Independencia de agentes externos.

¿Cuándo utilizar C.A?


Las recomendaciones generales son:
1. Largo plazo: ideal para software de vida larga y de gran envergadura. Operaciones de
negocio con amplia proyección
2. Modularización: Cuando se requieren frecuentes actualizaciones de componentes,
fuentes de datos, librerías o permanentes requerimientos que implican cambios de
fondo.
3. Sistemas distribuidos: especialmente granjas de servidores y microservicios.
4. Almacenes de datos diversos: esto es; fuentes de datos heterogéneas. SQL Server y
Oracle juntos, por ejemplo.
5. Software genérico: que son extendidos con el tiempo por terceros quienes podrán
realizar nuevas implementaciones, plugins, servicios propios, etc.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Compruebe sus conocimientos

Llene los espacios con el concepto correcto. Pueden sobrar términos o frases:

Frases: Core, Minimizar, Presentación, Martillo dorado, Clean Architecture.

1. Indica que no debemos dedicarnos solo a un tipo de


arquitectura.

2. La capa debe tener la API del proyecto.

3. Un objetivo principal de la arquitectura es los recursos.

4. permite separar la lógica de la implementación

5. La capa desconoce los detalles externos.


Tome un screen y envíe sus respuestas a vuelta de correo para retroalimentación

Verifique su comprensión

Relacione los elementos:


1. Core.
2. Infraestructura.
3. Persistencia.
4. Presentación.
5. Aplicación.

API, Frontend

Microservicios, mailing, Webservices

Conexión y gestión de datos.

CQRS, Validaciones

Interfaces, Entidades, Excepciones, BLL

Tome un screen y envíe sus respuestas a vuelta de correo para retroalimentación

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Después de esta lección aprenderá a…

Instalar y configurar las siguientes herramientas:


12
1. Visual Studio Community. Descargar aquí…
13
2. SQL Server Express o la versión de tu preferencia. Descargar aquí…
14
3. SSMS Descargar aquí…
4. Instalar IIS. Cuando instalas SQL Server se instala IIS 10.0 Express. Ver instrucciones a continuación para
instalar el Administrador de servicios de IIS desde Windows 10.

El Aprendizaje Hecho Fácil!

Instalando el administrador de IIS desde Windows

Paso 1:
Vaya al Panel de control > programas y características. Seleccione > Activar o desactivar la
características de Windows como se observa en la imagen:

Paso 2
Ubique la opción que aparece en la figura y marque todas las listas alusivas al Administrador de
IIS, como observa en la imagen:

12
https://visualstudio.microsoft.com/es/thank
https://visualstudio.microsoft.com/es/thank-you-downloading-visual-studio/?sku=Community&rel=17
studio/?sku=Community&rel=17
13
https://www.microsoft.com/es-es/sql
es/sql-server/sql-server-download
14
https://docs.microsoft.com/en-us/sql/ssms/download
us/sql/ssms/download-sql-server-management-studio-ssms?view=sql
ssms?view=sql-server-
ver15

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Después de esta lección aprenderá a…

1. Modelar una base de datos modelo ‘Escuela Norte’ haciendo uso de SQL Server.

El Aprendizaje Hecho Fácil!

El diseño de nuestro almacén de datos es bastante simplificado para facilitar el avance en el


desarrollo. Además podrá cambiar con el paso de las lecciones.

Los vídeo tutoriales los encontrará en la lista o sección LABORATORIOS ¡APLICA YA!

Laboratorio ¡Aplica ya!

VÍDEO N° 1

¡Aplica ya!! Vídeo tutorial, paso a paso.

01. APIs CON C.A. - Creando la base de datos.

El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Laboratorio ¡Aplica ya!

Aplicando C.A. al Proyecto modelo ‘Escuela Norte’

En la siguiente imagen
visualizamos la estructura de
nuestro proyecto Escuela Norte,
aplicando los conceptos
bosquejados anteriormente.
Podrán existir algunas variantes
dentro de cada capa:

Estructura
En la imagen se ilustra la
estructura inicial de un proyecto
aplicando los conceptos
de Clean Architecture (C.A.)

De hecho, será nuestra


estructura base para el proyecto
‘Escuela Norte’.

El proyecto de tipo API


EscuelaNorte, está desarrollado
con .NET Core, Blazor y C#.

A partir de este punto


aplicaremos al desarrollo Clean
Architecture.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Proyectos base
Haremos uso de las Bibliotecas de clase Estándar que nos ofrecen compatibilidad para otros
proyectos como .NET Framework.. En resumen, crearemos las siguientes capas relacionadas con
los proyectos .Net Core:

Capa Carpeta/Servicios
Proyecto: Api.EscuelaNorte
Presentación
Tipo: .NET Core API

Proyecto: Core.EscuelaNorte
Core/Dominio
Tipo: Class Library .NET Standard.

Proyecto: Infraestructura.EscuelaNorte
Infraestructura
Tipo: Class Library .NET Standard.

Proyecto: Testing.EscuelaNorte
Testing Tipo: Carpeta de soluciones
Carpetas: xUnitTest.EscuelaNorte; IntegracionTest.EscuelaNorte

Recuerde que para cada uno de los laboratorios, usted tendrá a mano:

1. La lista Check List paso a paso.


2. Un diagrama UML de secuencia.
3. El vídeo tutorial

El siguiente diagrama muestra la relación que debe configurarse entre los proyectos tipo C.A. El
diagrama nos permite visualizar las referencias entre las capas con Clean Architecture.

Observe que la capa Core no referencia a las capas externas por ser el núcleo de la aplicación.
Las capas más externas deben referenciarse entre ella y apuntan al corazón del sistema, es decir,
la capa Core.

El Core del negocio se encuentra centralizado en la capa más interna e independiente a las
capas interfaces y el modelo entre otros. El contenido de las capas externas se desarrolla en los
siguientes pasos a paso y vídeos tutoriales.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

UML: Diagrama de secuencia

El Aprendizaje Hecho Fácil!

A continuación encontrará, al igual que para cada lección, la lista Paso a paso.

CHECK LIST, Paso a paso

1. Crear un proyecto > .NET Core C# API vacío.


2. Crear las capas descritas anteriormente y que corresponden a la arquitectura Clean Architecture.
3. Agregar las carpetas en cada capa del proyecto como se observa en las imágenes anteriores relacionadas
con la estructura.
4. Referenciar los proyectos relacionados en las capas de la arquitectura dentro de la solución (en el vídeo
v
se explica la razón):
1. Capa Interfaz referencia a > Core, Infraestructura.
2. Capa Infraestructura a > Core.

5. Agregar capa de pruebas — —Unitarias y funcionales:


1. Agregar una > Carpeta de soluciones > Testing que contendrá dos archivos de
tipo xUnitTest para pruebas de unidad y de integración.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

6. Agregar los paquetes NuGet iniciales para el proyecto, a saber:

1. capa -> Infraestructura:


Microsoft.EntityFrameworkCore.SqlServer.
Microsoft.EntityFrameworkCore.Tools.
Microsoft.EntityFrameworkCore.Relational.
2. capa -> Presentación (API):
Microsoft.EntityFrameworkCore.Design
El Aprendizaje Hecho Fácil!

VÍDEO N° 2

¡Aplica ya! Vídeo tutorial, paso a paso.

02. APIs CON C.A. - Creando el proyecto

El Aprendizaje Hecho Fácil!

ADVERTENCIA

Para las siguientes lecciones debes tener diseñada la base de datos modelo referenciada en lecciones anteriores, o
un diseño de su preferencia.

El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
PARTE
Diseño. Series desde cero. https://vladodotnet.wordpress.com/
2
PARTE II: ABSTRACCIÓN,
PRACTICANDO SON SOLID,
REPOSITORY, DTO’s

Después de esta lección aprenderá a…

1. Conocer y aplicar los principios SOLID.


2. Entender qué es:
a. El acoplamiento o detalles de implementación y dependencias.
b. La Abstracción y desacoplamiento.
c. La Inyección de dependencia —DI.
d. La Inversión de Dependencias —IoC.
e. La importancia de las Interfaces.
f. El Ciclo de vida de DI.
3. Reconocer las técnicas básicas para aplicar DI.
4. Practicar con el laboratorio ¡Aplica ya! los principios anteriores.

¡Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Antes de sumergirnos en la estup


estupenda temática de esta sección, me
e ha parecido importante
dejar de entrada la definiciones básica de un concepto que usted ha venido encontrando y que
profundizaremos y aplicaremos en los laboratorios que forman parte del curso.

Abstracción

Este concepto forma parte de uno de los pilares de la Programación Orientada a Objetos (POO), e indica lo
siguiente:

Abstracción: “Una
Una abstracción es un tipo que describe un contrato, pero no proporciona una implementación
completa del contrato. Las abstracciones se suelen implementar como clases abstractas o interfaces,
interfaces e incluyen un
conjunto bien definido de documentac
documentación
ión de referencia que describe la semántica necesaria de los tipos que
15
implementan el contrato.”

Y como lo aprendí en mis años de pregrado: la abstracción es difícil de concebir y diseñar, especialmente cuando
de calidad y significancia se trata,, básicamente porque debemos acertar con los miembros que la conformarán
durante el ciclo de vida de un proyecto
proyecto,, ni más ni menos. Una abastracción con muchos miembros es complicada
de implementar. Pero si tiene pocos será de baja utilidad.

Su diseño es crítico a la hora de escoger el camino de la arquitectura y demás estructuras en un proyecto, porque
es imperioso que la abstracción proporcione una estupenda extensibilidad que brinde gran eficacia, como núcleo
precisamente de muchos patrones arquitectónicos, complementos, IoC, canalizaciones, etc.

Reconoceremos una buena abstracción cuando eliminamos dependencias y facilitamos las pruebas de
frameworks y testing, como es el caso de las pruebas unitarias. Y sobre todo, porque su mantenimiento y
actualización es mínima.

Y ese es el real reto.

El Aprendizaje Hecho Fácil!

15
Microsoft.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Practicando con los Principios SOLID


Se relacionan a continuación las definiciones de los principios aplicados al desarrollo de
software con calidad. Y desarrollaremos para cada uno, laboratorios explicativos y prácticos.

N° 1: Single Responsibility Principle (SRP)


Las clases y Módulos deben especializarse en una y solo una funcionalidad.

Por ejemplo: Una clase que realiza registro de matriculas, no debería implementar envíos de
correo institucionales. Para atender esto se crearía una clase especializada en realizar mailing o
servicios de mensajería. A esto se le conoce como SoC —Separation Of Concerns.

N° 2: Open/Closed Principle (OCP)


Nuestras clases deben ser reutilizadas sin tener que ser reeditadas nuevamente.

Deben comportarse como una Unidad Autónoma, atómica … que cambien los demás!
Por ejemplo si nuestra clase ‘Profesor’ tiene implementado un ActionResult con dos
condicionales que determinan si el profesor es de tiempo completo o parcial…. qué
sucedería si se crearán nuevas modalidades de liquidación como tiempo por horas? Así,
la clase Profesor no debe volver a ‘abrirse para rediseña o agregar nuevas funciones si
aplicásemos el principio Open/Closed. Por el contrario, esta funcionalidad debe ponerse
en clases especializadas aparte de los ActionResult y evitar la apertura de la clase
debidamente cerrada (close), como por ejemplo, los métodos o firmas de una API.

N° 3: Liskov (Bárbara Liskov) Substitution Principle (LSP):


Cada clase que hereda de otra puede usarse como su padre/base sin necesidad de conocer las diferencias entre
ellas.

Esto es: Si alguna de las subclases —clases hijas, no pueden implementar un método de la clase
Padre (abstracta, base) ….. entonces se viola el principio de sustitución que sería el de la hija! O
de otra manera: La clase base NO debe ‘comprender’ o conocer nada de las clases
hijas/derivadas.

Por ejemplo: La clase padre ‘cursos’ relaciona solo los cursos presenciales en una de sus firmas.
En la clase ‘registro matrícula’ —hija— se registran estudiantes a los cursos presenciales: son
estudiantes presenciales. ¿Qué sucede si aparece un estudiante de tipo corporativo que desea
matricularse pero en modalidad virtual? Esto implicaría modificar la clase base. Usted dirá: Ah!
diseño una nueva firma en la clase derivada. Es posible, pero… esa tarea le ha sido asignada a la
clase base! El método de registro heredado no sería válido para estudiantes que no pueden
asistir de manera virtual. Si se intenta el registro el sistema lanzará un Exception. Las clases hijas
no deben afectar o modificar la clase base.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

N° 4: Interface Segregation Principle (ISP)


‘Divide y vencerás’. Cuando diseñamos Interfaces, estas deben ser al igual que las clases: especializadas.

Por ejemplo para una interfaz tipo CRUD que maneja todos los métodos para realizar gestión
con datos, quedaría por fuera de su diseño un proceso de conexión, envío de datos, tipos de
impresión, etc. Debemos dividir las tareas en distintas interfaces, cada una con su contrato
especializado y además a ser utilizado en el 100%. Se violaría este principio si usted creará en
una interfaz firmas que nunca se utilizarán.

N° 5: Control Inversion Principle (IoC):


Los detalles se los dejo a las capas externas!

Este principio es fundamental para el diseño con Clean Architecture y lo verá aplicado en el
laboratorio de casi todas las lecciones del curso. Indica que las clases de niveles internos (Core)
en arquitecturas bien definidas no deben depender de las clases de niveles externos del
modelo —Infraestructura, Presentación, etc. Ambas deben aplicar el principio de POO:
la abstracción…. Gracias a la Inversión de Control (IoC). Ampliaremos más el principio anterior,
comprendiendo la Inyección de Dependencia (DI) en los laboratorio SOLID y apartados a
continuación.

Laboratorios ¡Aplica ya! practiando con SOLID

Ahora desarrollemos una serie de laboratorios prácticos con una aplicación de consola. Net, C#,
un par de capas básicas de la arquitectura Onion y los cinco casos prácticos con sus respectivas
soluciones, aplicando los principios SOLID.

Caso de estudio principio #1, SOLID SRP


Especializando las clases (Single Responsability Principles)

La siguiente serie de laboratorios desarrolla la lógica suficiente para poder aplicar una solución
a cada caso, haciendo uso de los principio SOLID. Se implementará código C# en una aplicación
tipo consola sin implementación de EF.

Pasemos a revisar el siguiente requerimiento del cliente Escuela Norte:

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Caso de estudio

Requerimiento N° 1: El cliente solicita un módulo adicional para su sistema de información “Escuela Norte” que
permita validar el proceso de las matriculas así:

1. El usuario autorizado para la gestión y validación de la matricula podrá ingresar por consola el código
del estudiante.
2. El backend de la aplicación debe atender los siguientes procesos:
a. Verificar que efectivamente el estudiante existe en la base de datos.
b. Una vez verificado el estudiante, se debe validar que existe el registro del pago de su
matricula semestral. (será simulado).
c. Confirmado el pago por el departamento contable, se procede a activar y asentar la matrícula
16
con todos los datos propios que formarán parte del Invoice.
d. Finalmente el servidor de comunicación deberá generar un correo electrónico adjuntando el
Invoice al correo del estudiante.
3. En cada proceso se debe informar al usuario autorizado del éxito de la transacción.

El Aprendizaje Hecho Fácil!

Para el caso tenemos


enemos la clase inicial class CasoSRP que gestiona el proceso de validación de la
matrícula, como se observa en el siguiente bloque, sin aplicar SOLID N°1:

Código

/// <summary>
/// CASO: SOLID #1: SINGLE RESPONSIBILITY PRINCIPLE
/// </summary>
public class CasoSRP
{
public async Task<bool
bool> ValidarEstudiante(Estudiante oEStudiante)
{
Console.WriteLine(
Console.WriteLine("\n");
Console.WriteLine(
Console.WriteLine("PROCESANDO...Validando estudiante\n");
);
return true;
}

public async Task<bool


bool> ValidarPago(int ID)
{
Console.WriteLine(
Console.WriteLine("PROCESANDO ...Consignación del pago\n");
);
return true;
}

16
Estándar de un documento
o o compromiso entre las partes (factura, recibo de caja, etc.)

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

public async Task<bool> RegMatricula(int ID)


{
Console.WriteLine("PROCESANDO ...generación del Invoice y " +
"registro de la matrícula\n");
return true;
}

public async Task<bool> MailMatricula(int ID)


{
Console.WriteLine("DESPACHANDO ... Invoice soporte...\n");
return true;
}
}
El Aprendizaje Hecho Fácil!

La clase class CasoSRP ha sido cargada con muchas responsabilidades y funcionalidades


distintas. Los requerimientos del cliente han sido implementados en una y solo una clase. Como
observa, es una clara violación al principio SOLID SRP, porque esta clase debe realizar todos los
procesos requeridos para la gestión y validación de una matrícula. ¿Funciona? Por supuesto que
funciona! Y así encontraremos miles de ejemplos y líneas de código en internet. Entonces ¿cuál
es el inconveniente principal?

Además de violar otros principios SOLID que veremos inmediatamente, tenemos:


 Dificultad para el mantenimiento de la implementación y actualizaciones. Por ejemplo,
si se crearan nuevas reglas de negocio —las verá má adelante— para cada uno de los
procesos, estos dependerían de esta clase y las clases externas encargadas de la
implementación. Cada vez que se requieran nuevas condiciones, actualizaciones o
ajustes que impliquen la clase public class CasoSRP desde otras secciones o módulos de
sistema, deberá ser modificada casi en su totalidad.
 El testing es practicamente inviable. Aplicar por ejemplo xUnit es imposible debido a
que la clase está compuesta por varios procesos, tareas y métodos, todos con misiones
distintas. Los casos de prueba se verán afectados porque se terminará involucrando y
probando todo a la vez!, La unidad de prueba no existe. No hay atomicidad.

Aplique ahora el principio SOLID SRP como solución al caso anterior, en el vídeo Caso#1.
Una vez realizada la refactorización y aplicación del principio SOLID SRP, el resultado final será
el siguiente: (Capa Core)

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Código

Mecanismo de abstracción (lo profundizará, practicará y comprenderá completamente más


adelante).
. Para el caso estamos creando como solución una Interface como mecanísmo de
abstracción,
, que contiene las firmas necesarias para atender el requerimiento del cliente:
cliente

public interface IGestionMatricula


{
Task<bool>
> ValidarEstudiante(Estudiante oEStudiante);
Task<bool>
> ValidarPago(
ValidarPago(int ID);
Task<bool>
> RegMatricula(
RegMatricula(int ID);
Task<bool>
> MailMatricula(
MailMatricula(int ID);
}

//Implementación de cada método


método/firma o tarea como un Servicio!
//Podría
Podría crear una implementación independiente por cada firma.

public class GestionMatricula : IGestionMatricula


{
public async Task<bool
bool> ValidarEstudiante(Estudiante oEStudiante)
{
Console.WriteLine(
Console.WriteLine("\n");
Console.WriteLine(
Console.WriteLine("PROCESANDO...Validando estudiante\n");
);
return true;
}

public async Task<bool


bool> ValidarPago(int ID)
{
… similar para el resto de los procesos solicitados…
}

El Aprendizaje Hecho Fácil!

Aplicando el concepto de abstracción que implica ir a lo general y no a los detalles, y aíslando la


clases de sus dependencias porque la Interfaz actuará de ‘puente’ y los servicios se especializan
en los procesos clave, ahora la clase solución (Capa Presentación, API o UI) tendrá este aspecto:

Código

public class SolucionSRP


{
private readonly IGestionMatricula _GestionMatricula;

public SolucionSRP(IGestionMatricula
(IGestionMatricula gestionMatricula) <- Constructor
{
_GestionMatricula
GestionMatricula = gestionMatricula;
}

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

public async Task<bool


bool> ValidarEstudiante(Estudiante oEStudiante)
{
await _GestionMatricula.ValidarEstudiante(oEStudiante);
return true;
}

NOTA:
Aunque se sigue la lógica similar a la implementación de servicios que usaremos en el diseño
API del curso, usted podrá crear un servicio independiente por cada proceso y una clase
solución. (ValidarEstudiante, ValidarPago, etc.)

El Aprendizaje Hecho Fácil!


En el código se ha hecho uso de una técnica que podrá profundizar en el siguiente apartado y
practicar ámpliamente. Se le conoce como DI o Inyección de dependencia. Aprenderá además
sus variantes.

Por qué una Interfaz

Es el contrato entre clases que obliga a cualquier clase del modelo a implementar precisamente TODO el contrato
17
declarado en dicha interfaz y así crear el mecanísmo de Abstracción: los detalles van en los niveles inferiores de
la arquitectura, para nuestro caso de tipo Onion
Onion.

Lo anterior lo profundizará y practicará más adelante.

El Aprendizaje Hecho Fácil!

Recuerde que la capa Presentación —para nuestro caso es el proyecto SOLID de tipo Console —
contiene el archivo > ProgramSolutionSRP.cs
ProgramSolutionSRP.cs, y el Void Main— con el punto to de inicio de la
aplicación y que requiere acceso
cceso o instanciación a la clase original refactorizada,, haciendo uso
de la línea: CasoSRP casoSRP = new CasoSRP(). Ha sido ajusta por la creación de un objeto de tipo
Interfaz que facilita el uso del
el servicio especializado para la clase principal, como se observa en
el siguiente código. A la técnica anterior se le conoce como patrón Singleton y lo verá más
adelante:

17
Validaciones, reglas y lógica de negocio, acceso a datos, Queries, etc.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Código

//Aplicando SOLID SRP

namespace SOLID.Principio_1.SRP
{
public class ProgramSolutionSRP
{
static async Task Main(
Main(string[] arg)
{

IGestionMatricula gestionMatricula = new GestionMatricula();

. . .
Estamos creando un objeto gestionMatricula
gestionMatricula, de tipo interfaz IGestionMatricula y por supuesto
un constructor para acceder a los servicios implementados .

El Aprendizaje Hecho Fácil!

De esta manera estamos dando cumplimiento al principio SRP.

Caso de estudio principio #2, SOLID OCP


¡No importune las clases! Extiendame pero no me modifique.

De acuerdo a la definición de este principio una clase debe poder extender el comportamiento
de otra clase sin modificar la original
original. Para este caso, el requerimiento es el siguiente:
siguiente

Caso de estudio

El cliente requiere un informe de las matriculas procesadas para cada día en formato tipo tabla electrónica y
Word.

El reto se presenta cuando el cliente interno o externo comience a requerir reportes en distintos formatos (Word,
PDF, JSON, XML, TXT, CVS, etc.). Esto implica abrir reiteradamente la clase para agregar nuevos métodos y
condicionales que determinen el reporte a procesar.

Lo anterior va en contra del principio SOLID OCP. Una vez diseñada una clase con base en la abstracción,
abstracción está no
debería sufrir
ufrir modificaciones o ‘abrirse (open). Desarrollemos el código inicial SIN aplicar el principio OCP, como
se observa en el siguiente bloque:
El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Código

public class CasoOCP //Código resumido…


{
public async Task<Matricula> CrearInforme(
Matricula oMatricula, int ID)
{
if(ID == 0)
{ InformeEXCEL(); }

else if(ID == 1)
{ InformeWord(); }

return oMatricula;
}

public async Task InformeEXCEL()


{
Console.WriteLine(
Console.WriteLine("EN PROCESO... Generando informe\n");
}

public async Task InformeWord()


{
Console.WriteLine(
Console.WriteLine("EN PROCESO... Generando informe\n");
}
}

El Aprendizaje Hecho Fácil!

Nos encontramos con dos procesos dentro de la clase CasoOCP.. E igual funciona!. Pero
recuerde: desarrollamos e implementamos pensando en el mantenimiento y extensibilidad.

Esta clase viola el principio N° 1 (SRP)


(SRP), y el N° 2 (OCP): ¿Qué sucede si con el tiempo se
requieren muchos más formatos para cada dependencia que solicite los informes,
informes como los
descritos anteriormente? Debemos agregar más y más métodos dos y condicionales adicionales…
adicion y
esto será para nada testeable!. Como puede concluir, se abriría una y otra vez la clase para ser
ajustada.

Por otra parte, observe el incremento de líneas por los if condicionales y swith.. case.
case Lo anterior
no coincide con las Buenas Prácticas y calidad de software. Respecto al estilo de codificación,
codifi en
el apartado relacionado con los patrones existen algunos casos para refactorizar este tipo de
casos comunes de codificación.

Observe la solución y el cambio


o al aplicar el principio OCP:

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Código
1. Aplicamos primero el principio N°1 SRP (ver caso anterior).
2. Seguidamente haremos uso del
el principio N°2 OCP. Crearemos una interfaz Genérica para la que
el formato
ato del informe es transparente. Esto es: Las capas internas deben desconocer los
detalles!
3. Y finalmente, ajustaremos
justaremos la capa Presentación (UI).

public class SolucionOCP


{
private readonly IGenerarInformes _generarInformes;

public SolucionOCP(IGenerarInformes
(IGenerarInformes generarInformes) <- Constructor
{
_generarInformes = generarInformes;
}

public async Task<bool


bool> CrearInforme()
{
await _generarInformes.NuevoInforme();
return true;

}
}
El Aprendizaje Hecho Fácil!

¡Estupendo!. ¿Nota la diferencia? Compárelas. Hemos aplicado además los principios


principio N° 1 y 5. Y
laa refactorización ha reducido y especializado la tarea de la clase SolucionOCP así:
 Solicita el servicio para la generación de informes aplicando Inyección de dependencia
(lo trataremos en poco con el principio N°5 IoC),), dejando los detalles de
implementación por fuera.
 Se eliminan condicionales if…else.
 Se aplica abstracción a traves de la interface IGenerarInformes de tal manera que para la
clase SolucionOCP es transparente
transparente, indiferente el tipo de formato del informe.
 Como resultado de lo anterior, tendremos una clase especilizada para la gestión de
cualquier solicitud de informes con un formato específico, el que sea solicitado por el
usuario,, esto es: NO requiere ser abierta nuevamente
nuevamente. Todo es transparente para la
interface IGenerarInformes como se observa en el código siguiente:

Código

public interface IGenerarInformes


{
Task <bool>
> NuevoInforme();
}

El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Este contrato obliga al resto de la aplicación a usar la firma Task <bool>


> NuevoInforme();.

Finalmente nuestra capa de presentación (UI) quedaría así:

Código

Una instancia para cada servicio independiente:

IGenerarInformes oExcel = new GenerarExcel();


IGenerarInformes oWord = new GenerarWord();

Ejemplo de la ejecucución del servicio…

await oExcel.NuevoInforme();

NOTA:
Para efectos de simplificación no se ha incluído, por ejemplo, un parámetro con el objeto
complejo ‘matricula’ que traería el registro del conci
conciliado
liado de las matrículas del día de la
base de datos.

¡APLIQUE YA! el caso en los vídeos de la lección.

El Aprendizaje Hecho Fácil!

Caso de estudio principio #3, SOLID LSP


Implementando la herencia correctamente

Revisando la definición de este principio de sustitución, las clases derivadas (hijas


hijas) deben poder
sustituirse por la clase base o madre
madre. Esto es: los objetos que deben producir por las clases hijas
pueden ser reemplazados, utilizados y comportarse exactamente como su clase base. Dicho de
otro modo: los métodos o firmas dervidas no son ni m más
ás ni menos que los métodos de la clase
base gracias a que los objetos de la clase base podrán ser reemplazados por objetos de las
clases derivadas,, es decir, cumplen el 100% de contrato de la firmas y demás miembros...
miembros ¡No
sobra ni falta nada!

¿Pero cómo se logra la sustitución? Gracias a los mecanísmos de la POO18. Recordemos:


Recordemos
 Composición:: los objetos tienen una relación de complementariedad o dependencia
para su funcionalidad. Es una especie de ‘simbiosos digital’. Si el objeto A que referencia
al objeto B se destruye, será igual para el B, gracias al ciclo de vida de A que controla
(referencia) la relación. Por ejemplo en una factura tenemos encabezado y detalle. Al
crear el objeto factura en memoria, el encabezado (objeto A) referencia al detalle (objeto
(objet

18
Programación Orientada a Objetos.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

B). Una vez cumplido el ciclo de vida del objeto A, no tendremos en la escena (memoria
principal) un objeto B aún con vida, deambulando por ahí.
 Agregación: una clase hace uso de otra para cumplir ciertas tareas pero su existencia no
depende de esta. El objeto A que contiene la referencia al objeto B, solicita la
agregación. El objeto B NO se destruirá si el objeto A finaliza su ciclo de vida. E
igualmente en sentido inverso.
 Delegación: transferir la responsabilidad o tarea a otra clase. El objeto A delega la tarea
al objeto B, y ambos son independientes en su ciclo de vida.
Este mecanísmo es usado cuando el objeto A no cuenta con recursos para realizar cierta
tarea obligatorias y que el objeto B sí puede.
Es precisamente este mecanísmo el que facilita el principio de sustitución para nuestro
caso de estudio.

El diagrama generalmente utilizado para describir estos mecanísmo POO se observa en la


siguiente imagen:

Revisemos los requerimientos para este caso donde aplicaremos el principio LSP:

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Caso de estudio

El cliente “Escuela Norte” ha solicitado el siguiente requerimiento:

 Se abrieron convocatorias para tomar cursos en las modalidades:


o Distancia
o Semi presencial
 Los estudiantes matriculados a distancia tendrán un descuento promocional del 25%
 Los estudiantes Semi presenciales recibiran el descuento del 15%
 Matrículas en la modalidad presencial no reciben bono promocional.
El Aprendizaje Hecho Fácil!

Vamos a crear la implementación de este requerimiento en el siguiente laboratorio y al igual


que los anteriores, iniciamos sin aplicar el principio Liskov Sustitution Principles, finalizando
finaliza con
la posterior refactorización para su aplicación. Crearemos además
emás dos variantes de solución:

Código

Caso sin aplicar LSP


//CLASE MADRE O BASE
public abstract class ModalidadEstudio <- Clase Abstracta!
{
protected int IDModalidad { get; set; }
public string?
? Modalidad { get; set; }

public abstract string DescuentoModalidad();


}

//IMPLEMENTACIÓN
public class ModalidadDistancia : ModalidadEstudio <- heredando…
{
public async Task ValidarDistancia(
ValidarDistancia(int id, string Nombre)
{
IDModalidad = id;
Modalidad = Nombre;
}

public override string DescuentoModalidad() <- Implemente miembros abstractos


haciendo uso de override
{
return "0.25";
;
}
}

public class ModalidadSemiPresencial : ModalidadEstudio


{
public async Task ValidarSemi(
ValidarSemi(int id, string Nombre)
{
IDModalidad = id;
Modalidad = Nombre;
}

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

public override string DescuentoModalidad()


{
return "0.15";
;
}
}

public class ModalidadPresencial : ModalidadEstudio


{
public async Task ValidarPresencial(
ValidarPresencial(int id, string Nombre)
{
IDModalidad = id;
Modalidad = Nombre;
}

public override string DescuentoModalidad()


{
throw new NotImplementedException(
NotImplementedException("No
"No aplica para esta modalidad");
modalidad"
}
}

Observe que para la clase ModalidadPresencial el descuento no es extensible por el tipo de


modalidad y se ha dejado por default una NotImplementedException. Este es un demo sencillo que
viola el principio LSP el cual indica que “Las clases derivadas deben poder sustituirse por la clase
base” que para el caso corresponde a abstract class ModalidadEstudio, o explicado de otra
manera, las firmas
rmas o miembros de la clase base deben poder implementarse en TODAS sus
clases hijas o derivadass precisamente gracias al principio de sustitución. El contrato debe
utilizarse al 100%!

Plus : clases abstractas

Aunque en este nivel usted debe conocer este concepto resumamos como plus adicional lo siguiente:

1. Las clases abstractas no permiten instanciación y son usadas como Base en la jerarquía de clases y
herencia. Puede definir métodos, a diferencia de las interfaces que solo pueden declarar las firmas a
implementar. Además podremos utilizar los modificadores de acceso (public, private
private,, etc.)
etc.
2. Las clases abstratas
ratas son ideales para:
a. La generación de objetos con un gran propósito común,
b. Grandes unidades funcionales a implementar por igual en todos los componentes derivados,
c. Generar múltiples versiones del componente y funcionalidad cambiante.
19
3. Son ideales para implementar Hooks

¡El Aprendizaje Hecho Fácil!

Para resolver lo anterior podríamos tomar varias vías. En nuestro caso haremos uso de una
interfaz y conservaremos la clase abstracta así:

19
Patrón HTTP ligero dedicados a la detección de eventos y envíos de Post

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Código

// Caso aplicando la solución con LSP

//CLASE MADRE O BASE


public abstract class BaseModalidad
{
protected int IDModalidad { get; set; }
public string?
? Modalidad { get; set; }
public double?
? PrecioMatriculas { get; set; } = 500;

public abstract double TotalPago(); // Se adiciona para ampliar el ejemplo.


}

Debido a que no todas las clases derivadas pueden ser sustituidas, se traslada el
método que calcula el descuento a una interfaz así:

//INTERFAZ
public interface IModalidad
{
public string DescuentoModalidad(); <- Viene de la clase base (abstracta)
}

Ahora nuestra clase solución tendrá el siguiente aspecto en su implementación:

//IMPLEMENTACIÓN
public class ModalidadDistancia : BaseModalidad, Imodalidad <- Puede heredar de varias clases
{
public async Task ValidarDistancia(
ValidarDistancia(int id, string Nombre)
{
IDModalidad = id;
Modalidad = Nombre;
Console.WriteLine(
Console.WriteLine("EN PROCESO... Verificando bono\n");
);
}

public string DescuentoModalidad()


{
return "0.25";
;
}

public override double TotalPago()


{
double TotalDcto = Convert.ToDouble(PrecioMatriculas * 0.25);
double TotalAPagar = Convert.ToDouble(PrecioMatriculas - TotalDcto);
return TotalAPagar;
}
}

Observe ahora cómo se implementa el método asociado a la modalidad “Presencial”

public class ModalidadPresencial : BaseModalidad, IModalidad


{
public async Task ValidarPresencial(
ValidarPresencial(int id, string Nombre)
{
IDModalidad = id;
Modalidad = Nombre;
Console.WriteLine(
Console.WriteLine("\n");
Console.WriteLine(
Console.WriteLine("EN PROCESO... Verificando bono\n");
);
}

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

public string DescuentoModalidad() <- Heredado de la interfaz!


{
return "... 0.0%
0.0%\n " +
"Esta modalidad no tiene descuentos especiales"
especiales";
}

public override double TotalPago() <- Se ejecuta sin problemas el cálculo


{
double TotalDcto = Convert.ToDouble( PrecioMatriculas * 0.0);
double TotalAPagar = Convert.ToDouble(PrecioMatriculas - TotalDcto);
return TotalAPagar;
}
}

//IMPLEMENTACIÓN SIMILAR PARA EL RESTO DE LAS MODALIDADES

El método abstract double TotalPago() es implementado


mentado en cada una de las clases derivadas.
El contrato se cumple al 100%.

Observe que podremos heredar tanto de la clase base abstracta como de la interfaz.

Ahora la implementación cumple el principio porque la clase base puede sustituirse por sus
clases derivadas que logran el 100% del contrato (para el ejemplo corresponde a los miembros
privados y el método abstrácto
abstrácto), e independientes del método para calcular el descuento que es
ahora parte de la interfaz.

Por supuesto, usted podrá crear una y solo una clase especializada por cada modalidad con su
respectiva abstracción como segunda variante a la implementación del principio N°3 así:

Variante caso principio LSP

Código
// Ahora implementemos esta variant
variante,
, creando una interfaz por cada tipo de
modalidad y su respectivo servicio: Caso aplicando la solución con LSP.
LSP

//CLASE MADRE O BASE


public abstract class BaseModalidad
{
protected int IDModalidad { get; set; }
public string?
? Modalidad { get; set; }
public double?
? PrecioMatriculas { get; set; } = 500;

public abstract double TotalPago();


}

//INTERFACES. Ejemplo para la modalidad ‘Distancia’

public interface IModalidadDistancia


{
Task ValidarDistancia(
ValidarDistancia(int id, string Nombre);
public string DescuentoModalidad();
}

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

//SERVICIO.
public class ModalidadDistancia :BaseModalidad, IModalidadDistancia
{
public async Task ValidarDistancia(int id, string Nombre)
{
IDModalidad = id;
Modalidad = Nombre;
Console.WriteLine("\n");
Console.WriteLine("EN PROCESO... Verificando bono\n");
}

public override string DescuentoModalidad()


{
return "0.25";
}

public override double TotalPago()


{
double TotalDcto = Convert.ToDouble(PrecioMatriculas * 0.25);
double TotalAPagar = Convert.ToDouble(PrecioMatriculas - TotalDcto);
return TotalAPagar;
}
}

Observe que una clase puede implementar una o más interfaces. En nuestro caso se implementan
los miembros de la clase abstracta y la respectiva interfaz. Además se hace uso de las firmas
completas. Notará que para la UI solo se requiere modificar el using por using
Core.SOLID.Servicios.

Queda como ejercicio para el estudiante aplicar el principio LSP para las modalidades
‘Semipresencial’ y ‘Presencial’.

Caso de estudio principio #4, SOLID ISP


Especialización y responsabilidad única de las interfaces

El principio de Interface Segregation es muy parecido al primer principio SOLID. Cada quien con
su tarea. Es mejor una interfaz que muchas interfaces cuando de procesos similares se trata. O
en otro sentido: una interfaz debe especializarse en su labor. Como se da cuenta en los
anteriores ejercicios, romper una principio SOLID impacta otros más.

Entonces una clase no está obligada a declarar métodos o funciones que no requiere o necesita,
y que forman parte del contrato de la interfaz a usar. Si sobran firmas entonces se está violando
el principio N° 4 ISP, y deben crearse las interfaces especializadas en dicha labor para trasladar
las firmas respectivas o sobrantes. Así, crear firmas en una interfaz para las clases que la
implementan y nunca las van a utilizar, es una violación al principio ISP, ¡Se cumple el 100% del
contrato! Este caso es muy parecido al caso anterior de la clase abstracta. Igualmente aplica
para las interfaces: el contrato debe implementarse en su totalidad. Recuerde que las interfaces
definen el comportamiento pero no la implementación.

Ahora revisemos los requerimientos para este caso donde aplicaremos el principio ISP:

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Caso de estudio

La “Escuela Norte” requiere el siguiente grupo de servicios para los estudiantes:

 Un estudiante podrá acceder a la app para reservar salones para eventos


 Tendrá la facilidad de reservar libros y solicitar la copia virtual a su correo
correo.
 Y un nuevo servicio para apoyar su rendimiento académico: reserva de tutorias extras como refuerzo,
refuerzo los
fines de semana.

El Aprendizaje Hecho Fácil!

El anterior requerimiento hace muy tentadora la alternativa de crear un servicio global que
proporcione las tres tareas. El caso de estudio sin aplicar el principio N°4 ISP quedaría así:

Código

//INTERFACE BASE

public interface IserviciosEstudiante <


<- Interface
{
Task GestionSalones(int
int id, string salon,
DateTime FechaReserva);

Task GestionPrestamos(
GestionPrestamos(int id, string ISBN,
DateTime FechaIni, DateTime FechaFin);

Task Tutorias(int id, int CodTutor, DateTime FechaTutoria);


}

El Aprendizaje Hecho Fácil!

Esta es una interface típica que va en contra del principio ISP.. Al igual que casos anteriores, su
especialización es difusa. Hace de todo un poco. Y usted ya comprende que esto afectará el
testing y mantenimiento futuro. Para su implementación tendremos:

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Código

//IMPLEMENTACIÓN DE LA INTERFACE BASE IserviciosEstudiante

public class CasoISP : IserviciosEstudiante


{

public async Task GestionSalones(


GestionSalones(int id, string salon,
DateTime FechaReserva)
{
Console.WriteLine(
Console.WriteLine("PROCESANDO...Gestionando préstamo\n");
}

public async Task GestionPrestamos(


GestionPrestamos(int id, string ISBN,
DateTime FechaIni, DateTime FechaFin)
{
Console.WriteLine(
Console.WriteLine("PROCESANDO...Gestionando préstamo\n");
}

public async Task Tutorias(


Tutorias(int id, int CodTutor,
DateTime FechaTutoria)
{
Console.WriteLine(
Console.WriteLine("PROCESANDO...Agenda de tutorías\n");
}
}
El Aprendizaje Hecho Fácil!

Y uno piensa: Genial! Todos los servicios centralizados. Pero ¿cómo podría por ejemplo
aplicarse una prueba xUnit a esta clase? Es inviable! Además estamos violando el principio SRP.
Como solución apliquemos el principio N° 4, Interfaces Segregation Principles así:

Código

//IMPLEMENTACIÓN DE INTERFACES
S SEGREGADAS: SERVICIO DE SALONES

namespace Core.SOLID.Interfaces
{
public interface IServicioSalones
{
Task GestionSalones(int
int id, string salon,
DateTime FechaReserva);
}
}

//IMPLEMENTACIÓN DE INTERFACES SEGREGADAS: SERVICIO PARA PRÉSTAMO DE LIBROS

namespace Core.SOLID.Interfaces
{

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

public interface IServiciosBiblioteca


{
Task GestionPrestamos(
GestionPrestamos(int id, string ISBN,
DateTime FechaIni, DateTime FechaFin);
}
}

//IMPLEMENTACIÓN DE INTERFACES SEGREGADAS: SERVICIO PARA RESERVA DE TUTORÍAS

namespace Core.SOLID.Interfaces
{
public interface IServiciosTutorias
{
Task Tutorias(int id, int CodTutor, DateTime FechaTutoria);
}
}

El Aprendizaje Hecho Fácil!

Estupendo diseño! Hemos aplicado el principio de segregación para especializar las interfaces
en cada una de sus responsabilidades. Ahora el usuario podrá hacer uso a través de la UI así:

Código

//IMPLEMENTACIÓN DE INTERFACES SEGREGADAS: SERVICIO DE SALONES

static async Task Main(string[]


[] args)
{
IServicioSalones oServicioSalones = new ServiciosSalones();
IServiciosBiblioteca oServiciosBiblioteca = new ServiciosBiblioteca();
IServiciosTutorias oServiciosTutorias = new ServiciosTutorias();

//Porción de código para consumir el servicio.

await oServicioSalones.GestionSalones
(IDEstu, "Salón A",
, DateTime.Today);
Console.WriteLine($"Salón
$"Salón reservado para el estudiante: \n " +
$"Carnet: {RegEstudiante.IDEstudiante}
{RegEstudiante.IDEstudiante}\n " +
$"Nombre: {RegEstudiante.NombreEstudiante}
{RegEstudiante.NombreEstudiante}\n");

… similar para el resto de código a desarrollar en el vídeo.


El Aprendizaje Hecho Fácil!

¿Notó algo?. La refactorización de la UI fue mínima. Solo se modificó nuestra línea de código
que referencia el objeto oServicioSalones Y eso es todo lo necesario para aplicar este principio.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Caso de estudio principio #5, SOLID IoC


Delegando el control de la cocina: modificando
odificando detalles sin afectar la lógica

Este principio nos ayuda a evitar que las clases internas o Core de la app, se vean afectadas por
nuevas implementaciones en las capas externas de la arquitectura. Esto equivale a una Alta
abstracción y baja cohesión o acople
acople. ¿Y entonces, cuál es el puente entre ambas capas?
Precisamente el mecanismo de abstracción
abstracción, haciendo uso de las interfaces y clases abstractas.

Así ¡los detalles dependerán de la abstracción! Y nuevamente, programamos pensando en el


mantenimiento, extensibilidad y testing. Con este principio, los detalles de implementación
serán ajenos al Core y aplicar pruebas como xUnit se facilitará gracias a la independencia de los
componentes. Instanciar clases y objetos complejos es una violación de este principio como lo
veremos en el laboratorio.

El chef y la cocina

Los componentes que conforman las capas exteriores y su carpintería, deben estar diseñados para encajar a
perfección en los mecanísmos de abstracción.

Un CHEF Corporativo Internacional se encarga de diseñar, establecer y programar las compras, el menú y la
innovación gastronómica. Son sus auxiliares de cocina los que se entenderán con los ingredientes, la sazón, la
limpieza y la preparación. Son los auxiliares quienes reciben las instrucciones, condic
condiciones
iones y estándares.

Sería un desperdicio que un CHEF internacional tenga que cocinar unos huevos o sacarle brillo a la estufa para
que las cosas de su organización marchen bien.

La carpintería
tería en el diseño de aplicaciones corresponde a las capas externas
externas.. Y estás entenderán y se comunicarán
con el Core a través del mecanísmo de abstracción.

El Aprendizaje Hecho Fácil!

Entonces ¿quién suministrará la dependencia? Como se estudio en el caso del principio SRP,
hacemos uso de técnicas como la Inyección de Dependencia (DI) que es una de las más
populares para poner a punto la IoC y así facilitar la comunicación entre el Core y las capas
externas dedicadas a la implementación y detalles.

Como observación final, aplicar TDD (Test Driven Development) no es posible si no existe IoD. Y
es precisamente este principio la base del patrón Factory.

Iniciemos identificando los nuevos requerimientos de la es


escuela
la para aplicar este principio.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Caso de estudio

La escuela requiere el diseño siguiente:

 La administración académica requiere un módulo que registre la asistencia a clase con la lectura
biométrica del estudiante.

El Aprendizaje Hecho Fácil!

Código

Tenemos entonces la implementacion inicial sin IoC:

public class ProgramCasoIoC


{
static async Task Main(
Main(string[] args)
{
RegistroIngresos oRegistroIngresos = new RegistroIngresos();
. . .

El Aprendizaje Hecho Fácil!

Observe la instanciación de una clase que gestiona el registro del ingreso a la clase
RegistroIngresos. Esto ocasiona fuerte acomplamiento de class ProgramCasoIoC. Previamente
hemos desarrollado la entidad ControlIngresos con propiedades para simular el almacenamiento
de datos como se observa en el siguiente código:

Código

namespace Core.SOLID.Entidades
{
public class ControlIngresos
{
public int IDIngreso { get; set; }
public int IDEstudiante { get; set; }
public DateTime FechaReg { get; set; }
}
}

El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Y por otra parte, en la capa > Infraestructura creamos la simulación de un patrón tipo Repository
RegistroIngresos haciendo uso del método void RegistrarIngreso

Código

using Core.SOLID.Entidades;

namespace Infraestructura.Repositorio
{
public class RegistroIngresos
{
public void RegistrarIngreso(
RegistrarIngreso(int idEstu,
DateTime FechaReg)
{
var RegIngresos = new ControlIngresos()
{
IDIngreso = 1,
IDEstudiante = idEstu,
FechaReg = FechaReg
};
}
}
}

El Aprendizaje Hecho Fácil!

Usted aprenderá a implementar este patrón y el genérico UoW en laboratorios más adelantados
del curso. Por el momento vamos a aplicar como solución el principio SOLID N°5 Inversión de
Control.. ¿Qué código cree que debe reemplazar la línea RegistroIngresos oRegistroIngresos = new
RegistroIngresos(); ? Observe el siguiente proceso de refactorización del caso:

Código

namespace Core.SOLID.Interfaces
{
public interface IServicioRegistroBio
{
void RegistrosBIO(int idEstu,
DateTime FechaReg);
}
}
El Aprendizaje Hecho Fácil!

¡Exacto! Usted lo previó. Ya comprende entonces el concepto de abstracción haciendo uso del
mecanismo de programación como se observa en este caso con la interfaz:

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

interface IServicioRegistroBio
Ahora implementemos la interfaz anterior creando el servicio:

Código

namespace Core.SOLID.Servicios
{
public class ServicioRegistroBio : IServicioRegistroBio
{

public void RegistrosBIO(


RegistrosBIO(int idEstu, DateTime FechaReg)
{
var RegIngresos = new ControlIngresos()
{
IDIngreso = 1,
IDEstudiante = idEstu,
FechaReg = FechaReg
};
}
}
}
El Aprendizaje Hecho Fácil!

Así, podremos acceder al servicio aplicando el principio IoD por el uso del mecanísmo ID

Código

static async Task Main(string[]


[] args)
{
IServicioRegistroBio oBIO = new ServicioRegistroBio();

oBIO.RegistrosBIO(IDEstu,FechaIngreso
IDEstu,FechaIngreso);

El Aprendizaje Hecho Fácil!

Finalmente hemos logrado desacoplar el servicio para el registro de los datos cuando un
estudiante asiste a clase.

Continúe ahora con la serie de laboratorios ¡Aplica ya! practicando son SOLID.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

VÍDEO: practicando con SOLID

¡Aplica ya! Vídeo tutorial, paso a paso.

Todos los vídeos de las prácticas con cada principio los encontrará relacionados
en el apendice A al final del curso.
El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Inversión de Control IoC e Inyección DI

De acuerdo al siguiente gráfico, la dirección de la dependencia de la aplicación está en la


dirección de los detalles de la implementación más no en la dirección de la abstracción.

La mayoría de las aplicaciones están escritas de tal manera que la dependencia en tiempo de
compilación fluye en la dirección de la implementación de detalles durante la ejecución. Es decir,
si la clase Z llama a un método de clase Y y la clase Y llama a un método de clase X, entonces,
en el tiempo de compilación, la clase Z dependerá de la clase Y y X y la clase Y dependerá de la
clase X. Esto equivale a un fuerte acoplamiento y dependencia en todo el modelo.
Aplicando en tonces el principio SOLID #5, observe el siguiente gráfico que facilita la
abstracción para el modelado de la lógica de una aplicación:

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

A este proceso de abstracción se le conoce como la técnica de inyección de dependencias —


DI— que hace posible aplicar el principio IoC gracias a que el control no se halla en cada una
de las clases. El flujo de control es gestionado por la implementación de abstracción
mediante interfaces que preccisamente toman ese control.

El principio IoC es una parte clave, diríamos crítica, para la construcción de aplicaciones poco
acopladas, ya que los detalles de implementación se pueden escribir para depender e
implementar abstracciones de nivel superior, en lugar de lo contrario. Como resultado, las
aplicaciones resultantes son más testeables, modulares y fáciles de mantener. Y este principio y
técnica lo aplicaremos en los laboratorios ¡Aplica ya! del curso.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

DI en pocas palabras

Inyección de Dependencia es la técnica que nos permite acceder a servicios configurados en una ubicación
central.

● Los servicios registrados en el marco se pueden insertar directamente en componentes y capas de la


aplicación.
● Las aplicaciones definen y registran servicios personalizados y los ponen a disposición de otras
aplicaciones a través de la inserción de dependencias.

Para el caso de Blazor y sus componentes, una vez que se han agregado los serv servicios
icios a la colección de servicios —
contenedor— se insertan en los componentes mediante la directiva @inject de Razor. Esto lo puede practicar en
el desarrollo de los laboratorio de este curso y del siguiente curso,, nivel avanzado II durante el desarrollo de una
Tienda Online con Blazor.
El Aprendizaje Hecho Fácil!

Técnicas para DI
Aquí un resumen de las distintas técnicas para aplicar Inyección de Dependencia.

Inserción de constructores
Los controladores de nuestra aplicación solicitan las dependencias de forma explícita a través de
constructores. ASP.NET Core tiene compatibilidad integrada con la inserción de dependencias.
Los servicios se agregan como un parámetro de constructor y el runtime
ntime resuelve el servicio
desde el contenedor de servicios. Normalmente, los servicios se definen mediante interfaces.
Esta técnica la usaremos ámpliamente en los vídeo tutoriales.

Inserción de acción con el atributo FromServices


FromServices permite la inserción de un servicio directamente en un método de acción —
ActionResult— sin usar la inserción de constructores.

Código

[HttpGet]
public List<Estudiantes> GetProduct
GetProduct([FromServices] IEstudiantesService EstudianteService)
{
return EstudianteService.
EstudianteService.Value;
}

El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Acceso a la configuración desde un controlador


El acceso a la configuración de la aplicación o a los valores de configuración desde un
controlador es un patrón habitual. El patrón de opciones que se describe en Patrón de opciones
en ASP.NET Core es el enfoque preferido para administrar la configuración. Por lo
general, IConfiguration no se inserta directamente en un controlador.

El endpoint inicial

Para efectos de simplificar y lograr avanzar hasta llegar al modelo completo aplicando todos los conceptos del
curso, haremos uso del endpoint Estudiante y Usuario. El diseño de los demás tienen la mísma lógica y servirá
para que el estudiante practique lo aprendido.
El Aprendizaje Hecho Fácil!

Inyectando dependencia —DI


Es importante comprender los principios SOLID a la hora de desarrollar los laboratorios ¡Aplica
ya! del curso. Haremos uso de estos con el paso de las lecciones.

Ejemplo aplicando el principio SOLID N° 5


De seguro ha notado en sus aplicaciones, las de una organización o de terceros, el uso
reiterativo de la cláusula new que termina acoplando un controlador al repositorio,
repositorio (más
20
adelante en el vídeo conocerá de repositorios ), o la instanciación y acoplamiento
del DbContext21 de modo explícito dentro de nuestros controladores. Aunque lo último es lo
más común, acoplar cualquier instancia entre clases que no sea de tipo abstracto no es una
buena práctica de desarrollo como lo veremos en los vídeos tutoriales. Detectar acoplamiento o
dependencias en un proyecto verificando por ejemplo la cláusula new es una buena guía.
Observe en el siguiente código acoplado:

20
Un repositorio está destinado a crear una capa de abstracción entre la capa de acceso a datos y la capa
de lógica empresarial de una aplicación. La implementación de estos patrones puede ayudar a aislar la
aplicación de los cambios en el almacén de datos y puede facilitar las pruebas unitarias automatizadas o
el desarrollo basado en pruebas (TDD) —Microsoft.
21
Combinación de patrones Unit Of Work y Repository. Corresponde a la clase especializada para interactuar
con los datos implementando un objeto único de tipo context.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Código

CASO 1:
[HttpGet]
public IActionResult GetListEstu()
{
var ObjEstudiante = new EstuRepositorio.GetEstuAll(); <- Acoplado
return Ok(ObjEstudiante);
(ObjEstudiante);
}

CASO 2:
[HttpGet]
public async Task<IActionResult> GetAsynEstuAll()
{

var ObjEstuAll = await _context.TblEstudiantes.ToListAsync();<


<- Acoplado
return Ok(ObjEstuAll);
(ObjEstuAll);

El Aprendizaje Hecho Fácil!

Explicación
En un escenario haciendo uso de un patrón como Repository,, en la capa API NO debería existir
una implementación como en el ejemplo anterior. El tipo de instanciación anterior
implica acoplamiento, tanto en el primer caso con la cláusula new por la dependencia con la
clase EstuRepositorio,, como en el segundo caso por la dependencia directa con la
clase DbContext instanciada a través de la variable
variable-objeto _context. Algo que debe ser
transparente en la codificación.

Ambos casos implican que para futuros cambios o migraciones, el desacoplamiento es muy alto
debido a que la clase (tipo repositorio
repositorio) que contiene el método GetEstuAll( ) está dependiendo
de una implementación
mplementación concreta y no una abstracta —de nivel superior,, que para este caso
depende de la implementación del repositorio
repositorio-clase EstuRespositorio,, ocasionando
ocasionan alto
acoplamiento y baja adhesión..

¿Qué pasaría si en un proyecto grande necesitáramos cambiar el proveedor de nuestro almacén


de datos subyacente?

Tendríamos que crear un nuevo repositorio especializado en la gestión de objetos para el nuevo
proveedor de datos que es lo correcto. Eso significa que… tendremos que modificar TODO
nuestro proyecto para ajustar cada new EstuRespositorio! y realizar los ajustes uno a uno. El

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

asunto es mucho más extenso si es un proyecto con cientos de ActionResult referenciando


eferenciando
clases de nivel inferior. ¡El procedimiento anterior viola el principio SOLID N° 5!

Así que en el siguiente vídeo ¡Aplica ya! haremos uso de la abstracción e implementaremos
código para aplicar el principio SOLID N°5, creando un Contenedor de e Servicios DI como el
que aparece a continuación donde ¡¡la abstracción toma el control!

Código

/LA ABSTRACCIÓN TOMA EL CONTROL!


.
.
.
private readonly IEstudianteRepo _estuRepo; <- Referenciando el mecanismo de abstracción.

public EstudianteController
EstudianteController( IEstudianteRepo estudianteRepo ) <- Constructor, DI
{ _estuRepo = estudianteRepo; }

[HttpGet]
public async Task<IActionResult> GetAsynEstuAll()
{
var ObjEstuAll = await _estuRepo.GetEstudiantes(); <- No existe acoplamiento.
Existe abstracción (Interfaz)
return Ok(ObjEstuAll);
(ObjEstuAll);
.
.
//EL CONTENEDOR DE SERVICIO DI
public void ConfigureServices
ConfigureServices(IServicesCollection services)
{
services.AddControllers();
();
services.AddTransient<IGetEstuRepositorio
IGetEstuRepositorio, GetEstuRepositorio>();
}

El Aprendizaje Hecho Fácil!

Explicación
En el contenedor de servicios ConfigureServices(IServicesCollection services) hemos inyectado
dependencia a través del servicio de este que referencia el repositorio particular
GetEstuRepositorio (todo lo trataremos pasos a paso en los vídeos), para nuestro caso haciendo
uso de la fuente de datos SQL Server para los datos. ¿Y si se necesitase implementar un
proveedor de datos como Oracle? Crearíamos todo el repositorio para Oracle aparte,
independiente y sencillamente referenciaríamos dicho repositorio cambiando el nombre en el
contenedor por otro como GetEstuRepoOracle
GetEstuRepoOracle…. ¡Esto es genial,
enial, un solo cambio! Gracias a
la abstracción representada en la Interface IGetEstuRepositorio. Ahora tome en cuenta los
siguientes conceptos resumidos:

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Inyección de dependencia

Patrón de software: Inyección de Dependencia —DI

1. Dependencia: Un Objeto depende de otro Objeto. Si una clase se modifica -> > todas las que dependan de
ésta por igual. El código de configuración se dispersa por todo el proyecto de software. Las pruebas
Unitarias no funcionan bien en este escenario.
Inyección: hace referencia
cia a ‘inyectar’ o aplicar el servicio en el constructor de la clase donde se usa. El
marco asume la responsabilidad de crear una instancia de la dependencia y deshacerse de ella cuando
ya no sea necesaria.22
Instanciación: Se crea por el servicio suministr
suministrado
ado en el contenedor. ¡Las instancias no suceden en la
clase!

2. Interfaz: Se usa el tipo concreto de la clase. Se utiliza la interfaz que lo implementa. Esta corresponde a
la abstracción. Lo anterior facilita cambiar la implementación que usa el controlador sin modificar el
controlador como lo veremos en el vídeo de la lección.

El Aprendizaje Hecho Fácil!

Plus

Existen varios framewoks especializados en el desarrollo y diseño de Inyecciónde dependencia.

Como parte de los recomendados:

23
 Spring.NET - Application Framework (springframework.net)
24
 Ninject - Open source dependency injector for .NET

¡El Aprendizaje Hecho Fácil!

22 Véase más adelante ‘Duración de un servicio’


23 https://www.springframework.net/examples.html
24 http://www.ninject.org/

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Asincronismo: Ciclo de vida de un servicio


En los laboratorios encontrará un uso extenso de las tareas asincrónicas. Asociado a esto y el
registro de servicios en el contenedor, el asincronismo nos facilita el control sobre el ciclo de
vida de los procesos.. Los objetos y sus servicios se pueden registrar con ciclos
iclos de vida:
vida
● Transitorio
● Con ámbito
● Singleton

Transitorio
Los servicios de duración transitoria se crean cada vez que el contenedor del servicio los solicita.
Esta duración funciona mejor para servi
servicios
cios sin estado ligeros. Registre los servicios transitorios
con AddTransient. En las aplicaciones que procesan solicitudes, los servicios transitorios se
eliminan al final de la solicitud. “Always different”

Con ámbito
En el caso de las aplicaciones web, una duración con ámbito indica que los servicios se crean
una vez por solicitud de cliente (conexión). Registre los servicios con ámbito con AddScoped.
En las aplicaciones que procesan solicitudes, los servicios con ámbito se eliminan al final de la
solicitud. “Changes
Changes only with scope
scope”

Duración de un servicio Singleton 25

Los servicios de duración de singleton se crean de alguna de las formas siguientes:


● La primera vez que se solicitan.
● Mediante el desarrollador, al proporcionar una instancia de implementación directamente al contenedor.
Este enfoque rara vez es necesario.

Cada solicitud siguiente de la implementación del servicio desde el contenedor de inserción de dependencias
utiliza la misma instancia. Si la aplicación requiere un comportamie
comportamiento
nto de singleton, permita que el contenedor de
servicios administre la duración del servicio. No implemente el modelo de diseño singleton y proporcione el código
para desechar el singleton. Si un tipo o fábrica se registra como singleton, el contenedor eli
elimina
mina el singleton de
manera automática. Registre los servicios singleton con AddSingleton.

Los servicios singleton deben ser seguros para los subprocesos y se suelen usar en servicios sin estado. En las
aplicaciones que procesan solicitudes, los servicios singleton se eliminan cuando ServiceProvider se elimina al
cerrarse la aplicación. Como no se libera memoria hasta que se apaga la aplicación, se debe tener en cuenta el
uso de memoria con un servicio singleton.
“Always the same”
El Aprendizaje Hecho Fácil!

25
Microsoft

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Los beneficios del asincronismo


O TAP (Modelo de Programación Asincrónica de Tareas)

El procesador realiza una serie de tareas para que una instrucción se ejecute, y adicionalmente
podrá hacer otras simultáneamente sin tener que esperar la finalización de estas. Es realizar
tareas, iniciando algunas, dejandolas en desarrollo pero bajo vig
vigilancia
ilancia mientras se concluyen
otras. Todo se maneja a través de hilos. En programación en paralelo, se necesitarán varios hilos,
y unos bloquearán a otros hasta que no se completa la tarea de estos.

En programación asincrónica, con un solo hilo se podrán controlar y realizar todas. Ls


instrucciones sincrónicas son ejecutadas e interpretadas por la computadora, bloqueando cada
instrucción hasta completar su tarea asignada y asi poder pasar a la siguiente declaración de
código. El asincronismo evita esto y facilita la escalabilidad horizontal reduciendo los costos de
CPU y demás. ¡Crear código sincrónicos para ejecutar tareas asincrónicas es una mala práctica!
En el mundo real, no va a pararse en la impresora a observar mientras imprime una lista de 100
páginas,
nas, dejando de lado otras tareas importantes.

Practicando con los ciclos de vida .Net Core


En el siguiente laboratorio crearemos una aplicación de consola y observaremos el
comportamiento de cada uno de los ciclos de vida descritos.

Laboratorio ¡Aplica Ya!

VÍDEO: Comportamiento de los ciclos de vida

¡Aplica ya! Vídeo tutorial, paso a paso.

La relación de los vídeos de este tema los encontrará en el apéndice B al final del libro.

El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Material adjunto

COMANDOS y código a utilizar en los laboratorios


Comando Scaffold
Scaffold-DbContext "Server=.
SQLExpress;Database=cursos;Trusted_Connection=True;" Microsoft.EntityFrameworkCo
re.SqlServer -OutputDir Models

Cadena de conexión
"ConnectionStrings": { "EscuelaNorte": "Server=. SQLExpress;Database=cursos; Tru
sted_Connection=True;"

El servicio
builder.Services.AddDbContext<cursosContext>(options => options.UseSqlServer("na
me=ConnectionStrings:EscuelaNorte"));

El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

UML: Diagrama de secuencia

El Aprendizaje Hecho Fácil!

Explicación:
El diagrama visualiza el resultado final al aplicar la Checklist paso a paso de los vídeos 3 y 4.

El actor realiza una solicitud request haciendo uso de la interfaz API de usuario. La aplicación ya
ha implementado:
1. Como se observa en el diagrama el contenedor de servicios donde se generan los
objetos creados y cuyo ciclo de vida depende del tipo de servicio implementado como se
estudió en el apartado Ciclo de vida de un servicio
servicio; evalúa la solicitud request del cliente
en tiempo de ejecución o runtime. Se hace uso de los mecanismos de abstracción a
través de las interfaces que ofrecen los servicios y su implementación obligatoria
relacionadaa con las firmas registradas en estas.
2. Como el request se hace a través de la API y un Endpoint que para efectos del laboratorio
de los vídeos 3 y 4, corresponde a una lista de estudiantes a través de HttpGet,
HttpGet el
contenedor de servicios llama el objeto que presta dicho servicio en la interfaz<Repo>
3. Ahora la implementación de la interfaz solicita al objeto repositorio el acceso a los datos
a través de la clase DbContext
DbContext.
Observe que se regresa el control a la interfaz y esta finaliza su ciclo de vida pasando
pasand el
control al controlador API quien recibió inicialmente el request.
4. En el controlador API se realiza la DI a través del constructor. La variable única generada
se utiliza para la instanciación de la interfaz que presta el servicio solicitado a través del
de
Endpoint que forma parte del CRUD. Observe que se accede al repositorio para ejecutar

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

la consulta asociada al Get


Get. Para hacer esto posible se crea el objeto ModelBuilder en el
DbContext que retorna el modelo válido con los datos solicitados desde el Repositorio.
5. Validado el modelo se obtienen finalmente los datos de la fuente a través del objeto
Building Object,, retornado al Repositorio.
6. La capa y el objeto Repositorio devuelve el response con los datos a la Interfaz de usuario.

Proceso estándar

El anterior diagrama muestra el paso a paso interno de la aplicación Blazor API.

Se entenderá cada vez que se replique en posteriores laboratorios, que usted podrá repasar o referenciar
refe la
anterior explicación que es similar.

El Aprendizaje Hecho Fácil!

Para esta lección haremos un gran avance y desarrollaremos dos (2) vídeos tutoriales ¡Aplica ya!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

CHECK LIST, Paso a paso

En los tres vídeos ¡Aplica ya! de esta lección desarrollaremos los siguientes pasos:
Vídeo 3
1. Crear el MODELO con la arquitectura Database First utilizando el comando Scaffold-DbContext.
DbContext.
Capa -> Infraestructura ->
> DAL
2. Configurar la conexión.
3. Agregar los servicios necesarios.
4. Migrar o pasar las Entidades generadas por el Scaffold en la capa anterior, para la capa –> Core -> DAL.
Y ajustar namespace respectivos.
5. Agregar un controlador tipo API vacío:
Capa -> Presentacion, API
Vídeo 4
6. Diseñar nuestro primer Repositorio -> EstudianteRepo.
7. Crear los mecanismos de implementación de Inyección de Dependencias —DI.
8. Registrar el servicio.
Capa: Presentación(API), Program.cs (Startup)
El Aprendizaje Hecho Fácil!

VÍDEO N° 3 y 4

¡Aplica ya! Vídeo tutorial, paso a paso.

03. APIs CON C.A. - El Modelo


04. APIs CON C.A. - El Repositorio y DI

El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Después de esta lección aprenderá a…

1. Definir qué son los DTO ——Data Transfer Object.


2. Comprender qué es el Mapeo.
3. Aplicar DTO y mapeo al proyecto Escuela Norte.
4. Controlar las Referencias circulares.
5. Practicar con el laboratorio ¡Aplica ya! los conceptos anteriores.

El Aprendizaje Hecho Fácil!

Los DTO
ASUNTOS A RESOLVER
En este punto de su progreso habrá notado que el despliegue de los datos y acceso a nuestro
almacén de datos subyacente muestra partes del código implementado
implementado.. Ahora encontramos
algunos asuntos a resolver.

Referencias circulares:: Este mensaje de error en aplicaciones API se genera debido a la relación
de nuestras entidades anidadas..

Fundamentalmente se debe a que nuestra API envía un response serializado que generalmente
es en formato JSON —de de código C# a JSON
JSON— ejecuta un escaneo o mapeo de TODAS las
entidades relacionadass en el modelo de datos. Esto incluye además todas las llaves foráneas —
FK— realizando el mapeo en ambas direcciones. Lo anterior ocasiona una Referencia Circular.
Circular
Recuerde que el modelo en nuestro proyecto se relaciona gracias a las entidades de
navegación para asociar la cardinalidad entre entidades (1:M, M:M, etc).

En el siguiente ejemplo, la propiedad de navegación,


public virtual ICollection <TblMatricula> TblMatriculas { get; set; } permite asociar nuestra
entidad TblEstudiante con la entidad TblMatricula por la cardinalidad de 1:M, donde igualmente
se referencia con la propiedad public virtual TblEstudiante? Estudiante { get; set; } es decir,
1 estudiante puede matricularse una o muchas veces, y ese registro pepertenece
rtenece solo a ese
estudiante como
omo se observa en el siguiente código:

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Código

public TblEstudiante()
{
TblMatriculas = new HashSet<TblMatricula>();
}

public int EstudianteId { get; set; }


public string NombreEstudiante { get; set; } = null!;
public string ApellidosEstudiante { get; set; } = null!;
public string EstadoEstudiante { get; set; } = null!;
public DateTime FechaReg { get; set; }

public virtual ICollection


<TblMatricula> TblMatriculas { get; set; }
}

El Aprendizaje Hecho Fácil!

Durante el mapeo esta propiedad generará la referencia circular

Propiedades expuestas al cliente


cliente:: habrá notado en el anterior laboratorio que en cada
solicitud —response— del cliente que hace uso o consume los servicios API, se despliegan los
datos mostrando el campo de navegación "tblMatriculas": [ ] también. ¡Esto debemos
solucionarlo!:

Código

//FORMATO JSON: respuesta al GET

[
{
"estudianteId": 1,
"nombreEstudiante": "Veronica"
"Veronica",
"apellidosEstudiante": "Brown"
"Brown",
"estadoEstudiante": "activo"
"activo",
"fechaReg": "2023-12-31T00:00:00"
31T00:00:00",
"tblMatriculas": []
},

¡El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

LA SEGURIDAD Y EL REPOSTEO
¿Qué información estamos desplegando al cliente? Toda la estructura de nuestro modelo: la
propiedad -> "tblMatriculas": [ ] está siendo expuesta y brinda pistas del diseño de la aplicación.

Un programador experimentado podría hacer uso del reposteo para insertar datos no n
autorizados….
…. registrando una nueva matrícula
matrícula, por ejemplo. Entonces, debemos evitar la
exposición delel diseño de una entidad con sus respectivas propiedades
propiedades, refactorizando
refactoriza código
para ajustar:

● Propiedades desplegadas de más: lo anterior conlleva a ocultar


tar propiedades para
reducir el tamaño de la carga y envío de datos.
● Acoplamiento de capas: Esto es: nuestro modelo actual aún persiste en el acoplamiento
entre la capa de servicio y la capa de datos. Debemos desacoplar como lo veremos en el
siguiente laboratorio.

Bugs

Modelos Relacionales

Los modelos relacionales tienen muchas propiedades y beneficios para el diseño de nuestros almacenes de datos
subyacentes. Uno de tantos es la actualización en cascada de los datos entre las entidades. Esto en una API es de
fácil manejo por parte de un cliente
ente avanzado con intenciones distintas y con conocimientos para generar desde
su aplicación código que actualice datos en cascada sin ninguna autorización.

¡Los DTO son la solución para esto.

¡El Aprendizaje Hecho Fácil!

Los Objetos de Transferencia de Datos (DTO) corresponden a objetos que definen CÓMO se
enviarán los datos a través de una red.

CARACTERÍSTICAS DE OBJETOS DTO


● Serializables:: Todo DTO debe ser serializable para viajar entre nodos.
● Readonly: Todo DTO debe sserer de solo lectura. Esto nos lleva a aplicarlos en métodos
que no impliquen operaciones del negocio.
● Multiplicidad: Esto indica que nuestros objetos DTO deben cargar datos de múltiples
fuentes y entidades.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Todo lo anterior nos lleva a crear estructuras de datos independientes de las entidades y el
modelo.. Y no menos importante es el impacto en el costo de la operación de transferencia de
ida y vuelta, debido a que con un objeto DTO será posible entregar muchos datos en una sola
llamada.

Los DTO

Los DTO son objetos de clases especializadas simples que no deben contener ninguna regla de negocio ni
requieren ser testeados mediante aplicación de pruebas como xUnit.

¡El Aprendizaje Hecho Fácil!

Ventajas
Un DTO permite:
1. Que el objeto remoto devuelva los datos completos al cliente en una sola llamada
remota.
2. Hacerlo reduciría la cantidad de llamadas de cuatro a una. En lugar de realizar varias
llamadas remotas, el cliente realiza una única llamada y luego interactúa con el DTO
localmente.

Un DTO es un contenedor simple para un conjunto de datos agregados que deben transferirse a
través de un proceso o un límite de red. No debe contener lógica empresarial y limitar su
comportamiento a actividades como la verificación de coherencia interna y la validación
validació básica.
Durante su diseño debemos tener cuidado de no hacer que el DTO dependa de nuevas
clases como resultado de la implementación de estos métodos. 26 Aplicaremos DTO en los
siguientes vídeos.

El automapeo nos permite convertir objetos basados en convenciones.

En nuestro proyecto esto implica mapear las propiedades que representan los campos en
nuestro almacén de datos subyacente de tal manera que simplificamos código
código.. Utilizaremos los
servicios
os ofrecidos en el paquete:

NuGet AutoMapper.Extensions.Microsoft.DependencyInjection.

El anterior proceso se requiere especialmente cuando hemos implementado objetos de tipo


DTO. Esto debido a que dichos objetos representan nuestras entidades de dominio como

26
Microsoft.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

entidades planas.. El trabajo de conversión se realiza de modo transparente al usuario facilitando


la funcionalidad en todas las capas de nuestro modelo y su consistencia.

Advertencia

Para proyectos existentes o para realización de mejoras corporativas donde hallan cientos de entidades y los
nombres de los campos del almacén de datos subyacente NO EQUIVALEN o no son iguales a las propiedades
establecidas en el modelo del proyecto tipos .NET Core o MVC, NO se recomienda la técnica de automapeo
automape debido
a lo dispendioso de referenciar y hacer equivaler cada una de estas.

¡El Aprendizaje Hecho Fácil!

UML: Diagrama de secuencia

¡El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Explicación
El anterior diagrama implementa dos nuevos objetos/capas:
1. DTO, 2. MAPPING.
2. Una vez implementado el objeto DTO, observe que en la capa repositorio se debe
primero ejecutar el mapeo previamente implementado.
3. Y además referenciado en el controlador API al refactorizar nuestro código.
4. Aplicando el patrón Singleton se accede al servicio registrado previamente IMapping en
el contenedor de servicios
servicios.
5. En este punto, el proceso continúa similar a lo explicado en lecciones anteriores hasta el
retorno de los datos como objeto complejo.
6. Es ahorara que los datos recibidos anteriormente son convertidos a objeto tipo DTO para
ser desplegados de manera transparente al usuario, evitando las inconveniencias
descritas en esta lección.

En el vídeo ¡Aplica ya! de esta lección haremos uso de los siguiente


siguientes pasos:

CHECK LIST, Paso a paso

Parte I

1. Crear nuestros Objetos DTO, replicando las entidades implicadas del modelo.
2. Definir las propiedades que estarán disponibles a la vista de los clientes que consumen los servicios API,
estableciéndose como propiedades planas.
3. Ajustar los métodos API implicados, en la capa -> Presentación.
4. Utilizar el Automapeo instalando el Nuget respectivo en:
Capa -> Infraestructura.
Capa -> Presentación.
5. Registrar las conversiones por automapeo en la carpeta respectiva:
Capa -> Infraestructura, DTO.
6. Registrar el servicio de automapeo y ubicar en el ensamblado cuáles son los profiles registrados para
mapear.
7. Implementar el automapeo en nuestros Controllers:
Capa -> Presentación.

Parte II

1. Implementar el control de las Referencias circulares haciendo uso del Nuget respectivo en la capa -> Api.
2. Habilitar el servicio para el control de Referencia circular, configurando el
método ReferenceLoopHandling.

¡El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

VÍDEOS N° 5 y 6

05. APIs Con C.A. - Dto Y Mapeo I


06. APIs Con C.A. - Dto Y Mapeo II

¡El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Reafirme sus conocimientos

Llene los espacios con el concepto correcto:

Frases: Mapeo, DI, LSP, Singleton


Singleton, Referencias ciculares, SRP, [FromServices],
DTO, Open/Close, DTOs, Interfaces, DBContext

1. nos permite aplicar Inyección de dependencia haciendo uso del


constructor.

2. No se recomienda hacer cuando los datos de la base de datos no


coinciden con el modelo.

3. Si no se pudiese utilizar existiría acoplamiento.

4. El es la capa que valida el modelo.

5. Con este
ste principio, , las clases y Módulos deben
especializarse en una y solo una funcionalidad.

6. es otra alternativa para acceder a los servicios del


contenedor.

7. Un me facilita controlar el despliegue de datos

8. Cuando se presentan debemos revisar la relaciones

entre entidades y aplicar

9. indica que nuestras clases deben ser reutilizadas sin


tener que ser reeditadas nuevamente

10. asegura que cada clase


lase que hereda de otra puede
usarse como su padre sin necesidad de conocer las diferencias entre ellas.

Tome un screen y envíe sus respuestas a vuelta de correo para retroalimentación

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
PARTE
Diseño. Series desde cero. https://vladodotnet.wordpress.com/
3
PARTE III: Reglas de negocio,
Excepciones, OpenApi

Después de esta lección aprenderá a…

1. Reconocer la importancia de refactorizar código.


2. Crear e implementar una Interfaz para refactorizar el DbContext.
3. Crear clases especializadas por cada Entidad del modelo.

¡El Aprendizaje Hecho Fácil!

¿Refactorizar cuándo?
El estándar general para el total máximo de líneas de código en un método C# está como
promedio entre 20-4040 líneas. De lo contrario el método se debe refactorizar en clases
especializadas acorde al servicio que presta cada método. ¡Divide y vencerás, aplicando SOLID!

CHECK LIST, Paso a paso

En el vídeo ¡Aplica ya! de esta lección desarrollaremos los siguientes pasos:

1. Refactorizar el DBContext:

Capa ->
> Infraestructura, DAL.
2. Crear la carpeta y clases especializadas por cada entidad del modelo.

Capa ->
> Infraestructura, DAL > Configuraciones.
3. Crear la interfaz genérica IBuilderTypeConfiguration para implementar la nueva configuración general

de nuestras entidades.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Capa ->
> Infraestructura, DAL > Configuraciones,

Instancia : DbContext, modelBuilder.ApplyConfiguration(


new <Entidad>Config());

Interfaz: IEntityTypeConfiguration<TblEntidad>
4. Migrar cada uno de los esquemas de nuestras entidades desde el DbContext:

Capa -> Infraestructura, DAL > DbContext

Migración a -> Infraestructura, DAL > clase ConfigEntidad.


5. Ajustar el código migrado acorde a nuestra interfaz.

6. Ajustar el DbContext para crear la instancia a la configuración autónoma de cada entidad en el modelo:

Capa -> Infraestructura, DAL > DbContext.

7. Realizar las pruebas pertinentes.

¡El Aprendizaje Hecho Fácil!

VÍDEO N° 7

07. APIs CON C.A. - Refactoring DbContext

¡El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Después de esta lección aprenderá a…

1. Comprender qué es la Capa Lógica de Negocios (Business Logical Layer).


2. Identificar Reglas de negocio iniciales.
3. Completar el CRUD en el repositorio.
4. Diseñar una capa BLL (Businnes Logical Layer) con abstracción.
5. Acceder a la capa reglas de negocio.
6. Implementar las primeras reglas comercia
comerciales o de negocio.

¡El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Material adjunto

Reglas de negocio iniciales

Inicialmente la empresa considera esencial implementar los siguientes requerimientos del negocio para el sano
funcionamiento de request y responses con los clientes, en este caso cliente interno que consumen los servicios de
su API:

1. Regla 1:Un estudiante NO podrá crearse con estado 'Activo'. Esto solo es posible si ha legalizado la
matrícula de su semestre. Es decir, la funcionaria encargada de las m
matrículas
atrículas es la persona autorizada
para modificar su estado a 'Activo'.

Solución:
1. Controlar el Request del cliente: endpoint > Post, crear nuevo estudiante.
2. Validación:
Capa > Presentación , API, Controller > Estudiante
Solicitar el servicio
io para aplicar la regla establecida
en la capa > Core, Servicio

¡El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

¿Qué son las reglas de negocio?


Son todas las decisiones de una organización que afectan o influyen en sus operaciones
comerciales y core o propósito del negocio. No deben confundirse con validaciones que forman
parte de la codificación, tipos de datos, sintaxis, etc.

Las reglas de negocio se deben implementar en una capa autónoma para facilitar la abstracción
o desacoplamiento, haciendo uso de los conceptos aplicados en lecciones anteriores como la DI,
el refactoring y testing.

La capacidad de crear reglas de negocio que aseguren una lógica empresarial consistente
independientemente de que la aplicación acceda a ese conjunto de datos, es imprescindible
para una operación comercial exitosa.

Definiendo reglas de negocio


Las reglas de negocio son lógica del lado del servidor que se utilizan para crear
recomendaciones basadas en inteligencia empresarial, requerimientos basados en políticas
corporativas, validaciones o aplicación de reglas gubernamentales, condiciones para otorgar
o restringir servicios o privilegios. También se utilizan en modelos de datos para establecer o
borrar valores, validar datos almacenados o mostrar mensajes de error, todos relacionados con
las operaciones comerciales y core del negocio.

Composición de una regla de negocio


Las reglas de negocio deben cumplir ciertas condiciones para hacerlas válidas y que estén
vigentes dentro de la capa BLL:
1. Condición: todas las reglas de negocio tienen una condición. Se trata de un
desencadenador que se usa para determinar —en función de los datos a gestionar— si
la regla de negocio debe ejecutarse. Una condición siempre se ejecuta como verdadera o
falsa; además es posible incluir más de una condición en una regla de negocio.
Ejemplo: Véase la regla de negocio N°1 en el vídeo tutorial de esta lección.

2. Acción: una acción es lógica, como ejemplo, restringir un procedimiento o función,


aplicar un descuento, otorgar un beneficio, generar un reporte especializado, etc.
Ejemplo: Una sala de cine establece como regla de negocio que los clientes que poseen
una Tarjeta de Cliente VIP si la utilizan más de 36 veces cada año, pueden acceder a
descuentos y obsequios.

3. Ámbito: las reglas de negocio pueden tener un ámbito local de la aplicación o global. La
regla puede ser aplicada por áreas o a toda la organización. Por ejemplo, si un curso
obtiene como promedio de rendimiento académico un 4.0 o superior, la regla de

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

negocio podría ser: se otorgará un descuento en la matrícula del 10%. El ámbito aplica a
los cursos de la ciudad X.

Diagrama de secuencia sin una capa de negocio


En este punto de su progreso, tenemos la especificación de procesos registrada en nuestro
diagrama de secuencia UML así:

Observe que no existe una capa de negocios. Esto significa que si se establece una regla de
negocio, de seguro deberá ser implementada, dentro de los ActionResult o incluso en el peor de
los casos, dentro de la base de datos como lo conocí en un software empresarial de una
multinacional. Hacerlo así, generará un fuerte acoplamiento y alta adhesión. Esto es algo muy
generalizado debido a la baja o nula aplicación de Buenas Prácticas de Desarrollo de Software.

Agregando reglas de negocio y criterios de aceptación


Debe saber que las organizaciones tienen reglas muy particulares dependiendo de su sector en
la economía y requerimientos de clientes internos y externos.

Las reglas de negocio se deben validar contra los repositorios. Esto puede conllevar a que se
afecte el modelo planteado por Clean Architecture. ¿Por qué?

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Fundamentalmente porque los repositorios


forman parte de la capa Infraestructura e
intentar instanciarlos desde la
capa Core implicaría que la capa más
interna dependa de una capa externa! (esto
sería una flecha desde core hasta
infraestructura).

Esto no va con la arquitectura limpia. Como


se observa en nuestro diagrama inicial la
capa core no hace referencia a las demás.

Solución: Hacer uso de las interfaces. Para


hacerlo posible, crearemos una capa
adicional para atender las reglas del
negocio.

Advertencia

El Core del negocio

Como se afirmó antes, las reglas de negocio NO deben generar dependencia con las capas externas a la capa
Core.

La capa Core debe ser el eje central de un sistema de información basado en Buenas Prácticas o arquitecturas
limpias que se concentran en:

1- Las entidades de dominio,


2- Las reglas de negocio. Y corresponde a la capa central y más interna en la
arquitectura limpia.

A este nivel se debe trabajar con ¡abstracciones! como lo veremos en el laboratorio vídeo tutorial de esta
lección.

¡El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Diagrama de secuencia incluyendo capa de servicios BLL.


Hasta este punto para acceder al almacén de datos subyacente la secuencia era:

Desde > Capa Api > Controlador > endpoint > Repositorio > Almacén de datos.
Ahora será: Capa Api > Controlador > endpoint > Servicio (BLL) > Repositorio > Almacén de
datos.

Una vez creados nuestros


stros servicios BLL, el diagrama de secuencia UML quedaría como se
observa en la imagen.

UML: Diagrama de secuencia

¡El Aprendizaje Hecho Fácil!

Explicación
Si existe una regla de validación personalizada —métodos
métodos distintos a los Verbos HTTP, se realiza
la verificación. Si el resultado es TRUE, implica que la regla es verdadera o está realizando su
papel para cumplir el requerimiento de negocio exigido. Esto devolverá un mensaje Bad
Request,500.

De lo contrario, si fue FALSE, indica que la regla se cumple porque el compilador la valida y
continúa el proceso solicitado. Es decir, es falso que no se cumple. En este caso, para nuestro

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

ejemplo, el usuario está intentando crear un nuevo usuario con Estado = “inactivo”,
“inactivo” se realiza el
registro y se envía el resultado o response al cliente Ok, o código 200 Success!.

Ahora manos a la obra… ¡Aplica ya!. Vamos a crear nuestra primera regla de negocios adjunta
en la caja “Material adjunto”, anterior. Diseñaremos nuestro nuevo nivel o capa BLL aplicando
aplica el
concepto de Abstracción visto hasta ahora.

Regla de negocio como servicio

Capa BLL

Para nuestra implementación, la BLL la realizaremos como un servicio en la respectiva carpeta de servicios del
mismo nombre, en la capa Core. Pero también podrá hacer uso de la carpeta BLL creada previamente para esto.

¡El Aprendizaje Hecho Fácil!

Advertencia

¿Reglas de validación y reglas de negocio?

No debemos confundir o mezclar estos dos conceptos: Las reglas de validación hacen referencia a los formatos
de datos, tamaño, tipo, sin son null, obligatorios, etc., y están fuertemente vinculadas en las validaciones contra
nuestro almacén de datos subyacente. Como ejemplos: verificar el número telefónico dependiendo del país, el
formato general introducido
ntroducido en una caja de texto para correos electrónicos, validar la edad, etc.

Las Reglas de negocio hacen referencia a las condiciones COMERCIALES de la empresa o cliente. Por ejemplo,
la regla de negocio N°1 indica que solo usuarios autorizados pueden modificar el estado de un estudiante y que el
usuario que registra nuevos estudiantes NO puede o no está autorizado para asignar el estado ‘activo’.

¡El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Parte I: Completando el CRUD del repositorio

CHECK LIST, Paso a paso

Parte I
Crear el resto de métodos CRUD:

1. Diseñar los métodos CRUD faltantes en este punto del desarrollo:


Capa -> Infraestructura, Repositorios.

2. Ajustar la Interfaz respectiva:

Capa -> Core, Interfaces.


Recuerda que el acceso a los repositorios se deben realizar por su respectiva interfaz. Así en los siguientes

pasos accederemos a nuestro almacén de datos subyacente instanciando la interfaz (nuestro mecanismo

de desacople) . . . No el DbContext: esto es responsabilidad del repositorio respectivo.


3. Implementar los métodos CRUD necesarios para validar la regla de negocio:

Capa: Presentación, Constructor.


4. Registrar el o los servicios relacionados con las reglas de negocio, de la capa BLL —Interface.
Interface.

5. Definir con el cliente las reglas de negocio requerid


requeridas
as por la empresa. Para nuestro caso, la regla N°1.

Estas conforman los criterios de aceptación que equivalen a las validaciones implicadas en la reglas.

6. Implementar la regla de negocio N°1.


¡El Aprendizaje Hecho Fácil!

VÍDEO N° 8

08. APIs CON C.A. - CRUD en el repositorio

¡El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Partes II: Implementando la regla de negocio N° 1.

CHECK LIST, Paso a paso

Parte II

Crearemos el nivel de la BLL que contendrá los métodos CRUD API necesarios para llamar las firmas
del repositorio relacionado, aludiendo a la entidad implicada en la regla de negocio.

1. Crear la carpeta o folder que contendrá las reglas de negocio que conforman la BLL. Podrá hacer uso del
folder ‘BLL’ o crear la interfaz de la regla de negocio dentro de la carpeta > ‘Servicios’.
Capa -> Core, Servicios.
2. Agregar siempre una clase por cada entidad implicada que requiere la prestación del servicio para
aplicar las reglas de negocio.
Capa -> Core, Servicios —BLL.
BLL.
3. Crear la nueva interfaz del servicio de la capa BLL:
Capa: -> Core, Servicios.
4. Trasladar la interfaz a la carpeta y capa indicada:
Capa: Core, Interfaces.
Actualizar el namespace.
5. Instanciar desde la capa BLL el repositorio haciendo uso del servicio prestado por su interfaz. Recuerde
que accedemos a los repositorios por abstracción gracias a nuestros mecanismos de desacople:
Capa > Core, Interfaces, IRepo.cs
En Capa > Core, Servicios. ??
6. Generar los métodos CRUD definidos en el contrato de la interfa
interfaz,
z, o en su caso los métodos
personalizados para validar la regla de negocio:
Capa: Core, Servicios (o BLL).
7. Modificar el mecanismo para DI y las referencias en el controlador a la capa BLL:
Capa: Presentación, Controller.
8. Implementar los métodos CRUD neces
necesarios para validar la regla de negocio:
Capa: Presentación, Constructor.
9. Registrar el o los servicios relacionados con las reglas de negocio, de la capa BLL —Interface.
Interface.
10. Definir con el cliente las reglas de negocio requeridas por la empresa. Para nuestro caso,
ca la regla N°1.
Estas conforman los criterios de aceptación que equivalen a las validaciones implicadas en la reglas.
11. Implementar la regla de negocio N°1.

¡El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

VÍDEO N° 9

09. APIs CON C.A. - Capa de negocio I


¡El Aprendizaje Hecho Fácil!

Verifique su aprendizaje

Llene los espacios con el concepto correcto. Pueden sobrar términos o frases:

Frases: Repositorios, Controlador , Core, Infraestructura, Repositorio,


Desencadenador, Validaciones, Reglas de negocio, Ámbito, Servicios.

6. corresponden a las decisiones que afectan las


operaciones comerciales y core del negocio.

7. El puede ser de alcance local o global. Es decir, la


regla puede ser aplicada a una sección, área o a toda la organización.

8. Las reglas de negocio se deben validar contra los .


9. Las reglas de negocio no deben crear dependencia a la capa

.
10. Las reglas de negocio se encuentran entre los objetos
objetos-capas
capas

y el .
11. Como Buenas Prácticas la capa de negocio generalmente se incluye en la

capa de como parte de la capa Core.

12. NO deben confundirse las reglas de negocio con las

Tome un screen y envíe


nvíe sus respuestas a vuelta de correo para retroalimentación

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Después de esta lección aprenderá a…

1. Completar el diseño de los métodos API CRUD en el endpoint ‘Estudiante‘.


2. Clasificar las clases de códigos de estado HTTP.
3. Identificar los niveles de manejo de excepciones y filtros.
4. Reconocer los tipos de registros de filtros.
5. Distinguir validaciones de reglas de negocio.
6. Diseñar el filtro para el control centralizado de Excepciones.

¡El Aprendizaje Hecho Fácil!

Códigos de estado
Los códigos de estado se definen en la sección 10 de RFC 2616.27 Puede obtener las
especificaciones actualizadas en RFC 7231.

Los códigos de estado de respuesta HTTP indican si se ha completado satisfactoriamente una


solicitud HTTP específica. Las respuestas se agrupan en cinco clases:

Respuestas informativas (100-103)


103)
● 100 Continue
Esta respuesta provisional indica que todo hasta ahora está bien y que el cliente debe
continuar con la solicitud o ignorarla si ya está terminada.
● 101 Switching Protocol
Este código se envía en respuesta a un encabezado de solicitud Upgrade (en-US)
(en por el
cliente e indica que el servidor acepta el cambio de protocolo propuesto por el agente
de usuario.
● 102 Processing (WebDAV (en-US))
Este código indica
ica que el servidor ha recibido la solicitud y aún se encuentra
procesandola, por lo que no hay respuesta disponible.
● 103 Early Hints (en-US)
Este código de estado está pensado principalmente para ser usado con el
encabezado Link, permitiendo que el agente de usuario empiece a pre-cargar cargar recursos
mientras el servidor prepara una respuesta.

27
Estándares para los códigos HTTP. Véase el link https://www.rfc-editor.org/rfc/rfc2616
editor.org/rfc/rfc2616

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Respuestas satisfactorias (200-299)


● GET: El recurso se ha obtenido y se transmite en el cuerpo del mensaje.
● HEAD: Los encabezados de entidad están en el cuerpo del mensaje.
● PUT o POST: El recurso que describe el resultado de la acción se transmite en el cuerpo
del mensaje.
● TRACE: El cuerpo del mensaje contiene el mensaje de solicitud recibido por el servidor.

● 200 OK
La solicitud ha tenido éxito. El significado de un éxito varía dependiendo del método
HTTP
● 201 Created
La solicitud ha tenido éxito y se ha creado un nuevo recurso como resultado de ello. Ésta
es típicamente la respuesta enviada después de una petición PUT.
● 202 Accepted
La solicitud se ha recibido, pero aún no se ha actuado. Es una petición “sin compromiso”,
lo que significa que no hay manera en HTTP que permite enviar una respuesta asíncrona
que indique el resultado del procesamiento de la solicitud. Está pensado para los casos
en que otro proceso o servidor maneja la solicitud, o para el procesamiento por lotes.
● 203 Non-Authoritative Information
La petición se ha completado con éxito, pero su contenido no se ha obtenido de la
fuente originalmente solicitada, sino que se recoge de una copia local o de un tercero.
Excepto esta condición, se debe preferir una respuesta de 200 OK en lugar de esta
respuesta.
● 204 No Content (en-US)
La petición se ha completado con éxito pero su respuesta no tiene ningún contenido,
aunque los encabezados pueden ser útiles. El agente de usuario puede actualizar sus
encabezados en caché para este recurso con los nuevos valores.
● 205 Reset Content (en-US)
La petición se ha completado con éxito, pero su respuesta no tiene contenidos y además,
el agente de usuario tiene que inicializar la página desde la que se realizó la petición,
este código es útil por ejemplo para páginas con formularios cuyo contenido debe
borrarse después de que el usuario lo envíe.
● 206 Partial Content
La petición servirá parcialmente el contenido solicitado. Esta característica es utilizada
por herramientas de descarga como wget para continuar la transferencia de descargas
anteriormente interrumpidas, o para dividir una descarga y procesar las partes
simultáneamente.
● 207 Multi-Status (WebDAV (en-US))
Una respuesta Multi-Estado transmite información sobre varios recursos en situaciones
en las que varios códigos de estado podrían ser apropiados. El cuerpo de la petición es
un mensaje XML.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

● 208 Multi-Status (WebDAV (en-US))


El listado de elementos DAV ya se notificó previamente, por lo que no se van a volver a
listar.
● 226 IM Used (HTTP Delta encoding)
El servidor ha cumplido una petición GET para el recurso y la respuesta es una
representación del resultado de una o más manipulaciones de instancia aplicadas a la
instancia actual.

Redirecciones (300 – 308)


● 300 Multiple Choice (en-US)
Esta solicitud tiene más de una posible respuesta. User-Agent o el usuario debe escoger
uno de ellos. No hay forma estandarizada de seleccionar una de las respuestas.
● 301 Moved Permanently (en-US)
Este código de respuesta significa que la URI del recurso solicitado ha sido cambiado.
Probablemente una nueva URI sea devuelta en la respuesta.
● 302 Found
Este código de respuesta significa que el recurso de la URI solicitada ha sido cambiado
temporalmente. Nuevos cambios en la URI serán agregados en el futuro. Por lo tanto, la
misma URI debe ser usada por el cliente en futuras solicitudes.
● 303 See Other (en-US)
El servidor envía esta respuesta para dirigir al cliente a un nuevo recurso solicitado a otra
dirección usando una petición GET.
● 304 Not Modified
Esta es usada para propósitos de “caché”. Le indica al cliente que la respuesta no ha sido
modificada. Entonces, el cliente puede continuar usando la misma versión almacenada
en su caché.
● 305 Use Proxy
Fue definida en una versión previa de la especificación del protocolo HTTP para indicar
que una respuesta solicitada debe ser accedida desde un proxy. Ha quedado obsoleta
debido a preocupaciones de seguridad correspondientes a la configuración de un proxy.
● 307 Temporary Redirect (en-US)
El servidor envía esta respuesta para dirigir al cliente a obtener el recurso solicitado a
otra URI con el mismo método que se usó la petición anterior. Tiene la misma semántica
que el código de respuesta HTTP 302 Found, con la excepción de que el agente
usuario no debe cambiar el método HTTP usado: si un POST fue usado en la primera
petición, otro POST debe ser usado en la segunda petición.
● 308 Permanent Redirect (en-US)
Significa que el recurso ahora se encuentra permanentemente en otra URI, especificada
por la respuesta de encabezado HTTP Location. Tiene la misma semántica que el código
de respuesta HTTP 301 Moved Permanently, con la excepción de que el agente

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

usuario no debe cambiar el método HTTP usado: si un POST fue usado en la primera
petición, otro POST debe ser usado en la segunda petición.

Errores de cliente (400 – 451)


● 400 Bad Request
Esta respuesta significa que el servidor no pudo interpretar la solicitud dada una sintaxis
inválida.
● 401 Unauthorized
Es necesario autenticarse para obtener la respuesta solicitada. Esta es similar a 403, pero
en este caso, la autenticación es posible.
● 403 Forbidden (prohibido)
El cliente no posee los permisos necesarios para cierto contenido, por lo que el servidor
está rechazando la petición y otorga una respuesta apropiada.
● 404 Not Found
El servidor no pudo encontrar el contenido solicitado. Este código de respuesta es uno
de los más famosos dada su alta ocurrencia en la web.
● 405 Method Not Allowed (en-US)
El método solicitado es conocido por el servidor pero ha sido deshabilitado y no puede
ser utilizado. Los dos métodos obligatorios, GET y HEAD, nunca deben ser
deshabilitados y no deberían retornar este código de error.
● 406 Not Acceptable (en-US)
Esta respuesta es enviada cuando el servidor, después de aplicar una negociación de
contenido servidor-impulsado, no encuentra ningún contenido seguido por el criterio
dado por el usuario.
● 407 Proxy Authentication Required (en-US)
Esto es similar al código 401, pero la autenticación debe estar hecha a partir de un proxy.
● 408 Request Timeout
Esta respuesta es enviada en una conexión inactiva en algunos servidores, incluso sin
alguna petición previa por el cliente. Significa que el servidor quiere desconectar esta
conexión sin usar. Esta respuesta es muy usada desde algunos navegadores, como
Chrome, Firefox 27+, o IE9, que usan mecanismos de pre-conexión HTTP para acelerar la
navegación. También hay que tener en cuenta que algunos servidores simplemente
desconecta la conexión sin enviar este mensaje.
● 409 Conflict (en-US)
Esta respuesta puede ser enviada cuando una petición tiene conflicto con el estado
actual del servidor.
● 410 Gone (en-US)
Esta respuesta puede ser enviada cuando el contenido solicitado ha sido borrado del
servidor.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

● 411 Length Required (en-US)


El servidor rechaza la petición porque el campo de encabezado Content-Length no está
definido y el servidor lo requiere.
● 412 Precondition Failed (en-US)
El cliente ha indicado pre-condiciones en sus encabezados la cual el servidor no cumple.
● 413 Payload Too Large
La entidad de petición es más larga que los límites definidos por el servidor; el
servidor puede cerrar la conexión o retornar un campo de encabezado Retry-After.
● 414 URI Too Long (en-US)
La URI solicitada por el cliente es más larga de lo que el servidor está dispuesto a
interpretar.
● 415 Unsupported Media Type (en-US)
El formato multimedia de los datos solicitados no está soportado por el servidor, por lo
cual el servidor rechaza la solicitud.
416 Requested Range Not Satisfiable (en-US)
● El rango especificado por el campo de encabezado Range en la solicitud no cumple; es
posible que el rango está fuera del tamaño de los datos objetivo del URI.
● 417 Expectation Failed (en-US)
Significa que la expectativa indicada por el campo de encabezado Expect solicitada no
puede ser cumplida por el servidor.
● 418 I'm a teapot
El servidor se rehúsa a intentar hacer café con una tetera.
● 421 Misdirected Request
La petición fue dirigida a un servidor que no es capaz de producir una respuesta. Esto
puede ser enviado por un servidor que no está configurado para producir respuestas por
la combinación del esquema y la autoridad que están incluidos en la URI solicitada
● 422 Unprocessable Entity (en-US) (WebDAV (en-US))
La petición estaba bien formada pero no se pudo seguir debido a errores de semántica.
● 423 Locked (WebDAV (en-US))
El recurso que está siendo accedido por terceros y está ocupado, bloqueado.
● 424 Failed Dependency (WebDAV (en-US))
La petición falló debido a una falla de una petición previa.
● 426 Upgrade Required (en-US)
El servidor se rehúsa a aplicar la solicitud usando el protocolo actual pero puede estar
dispuesto a hacerlo después que el cliente se actualice a un protocolo diferente. El
servidor envía un encabezado Upgrade en una respuesta para indicar los protocolos
requeridos.
● 428 Precondition Required (en-US)
El servidor origen requiere que la solicitud sea condicional. Tiene la intención de
prevenir problemas de ‘actualización perdida’, donde un cliente OBTIENE un estado del

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

recurso, lo modifica, y lo PONE devuelta al servidor, mientras un tercero ha modificado el


estado del servidor, llevando a un conflicto.
● 429 Too Many Requests (en-US)
El usuario ha enviado demasiadas solicitudes en un periodo de tiempo dado.
● 431 Request Header Fields Too Large (en-US)
El servidor no está dispuesto a procesar la solicitud porque los campos de encabezado
son demasiado largos. La solicitud puede volver a subirse después de reducir el tamaño
de los campos de encabezado solicitados.
● 451 Unavailable For Legal Reasons (en-US)
El usuario solicita un recurso ilegal, como alguna página web censurada por
algún gobierno

Errores de servidor (500 – 511)


● 500 Internal Server Error
El servidor ha encontrado una situación que no sabe cómo manejarla.
● 501 Not Implemented (en-US)
El método solicitado no está soportado por el servidor y no puede ser manejado. Los
únicos métodos de los que los servidores requieren soporte (y por lo tanto no deben
retornar este código) son GET y HEAD.
● 502 Bad Gateway
Esta respuesta de error significa que el servidor, mientras trabaja como una puerta de
enlace para obtener una respuesta necesaria para manejar la petición, obtuvo una
respuesta inválida.
● 503 Service Unavailable
El servidor no está listo para manejar la petición. Causas comunes puede ser que el
servidor está caído por mantenimiento o está sobrecargado. Hay que tomar en cuenta
que junto con esta respuesta, se debe diseñar una página usuario-amigable explicando
el problema. Estas respuestas deben ser usadas para condiciones temporales y el
encabezado HTTP Retry-After: debería, si es posible, contener el tiempo estimado antes
de la recuperación del servicio. El webmaster debe también cuidar los encabezados
relacionados al caché que son enviados junto a esta respuesta, ya que estas respuestas
de condición temporal deben usualmente no estar en el caché.
● 504 Gateway Timeout
● Esta respuesta de error es dada cuando el servidor está actuando como una puerta de
enlace y no puede obtener una respuesta a tiempo.
● 505 HTTP Version Not Supported
La versión de HTTP usada en la petición no está soportada por el servidor.
● 506 Variant Also Negotiates (en-US)
El servidor tiene un error de configuración interna: negociación de contenido
transparente para la petición resulta en una referencia circular.
● 507 Insufficient Storage (en-US)

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

El servidor tiene un error de configuración interna: la variable de recurso escogida


está configurada para acoplar la negociación de contenido transparente, y no es por lo
tanto un punto final adecuado para el proceso de negociación.
● 508 Loop Detected (en-US) (WebDAV (en-US))
El servidor detectó un ciclo infinito mientras procesaba la solicitud.
● 510 Not Extended (en-US)
Extensiones adicionales para la solicitud son requeridas para que el servidor las cumpla.
● 511 Network Authentication Required (en-US)
El código de estado 511 indica que el cliente necesita autenticar para ganar acceso a la
red.

Control personalizado de excepciones


De seguro ha notado el resultado de una excepción no controlada que genera un mensaje sin
formato, bastante técnico, ilegible y que confundirá al cliente final, como se observa en la
imagen:

A la página anterior se le conoce como página de excepción del desarrollador que despliega
el seguimientos de pila detallado para errores del servidor. En entornos que son de desarrollo se
puede usar middleware de control de excepciones para producir una carga de error. Pero en el
entorno de producción, el cliente necesita claridad.

Filtro de errores: IExceptionFilter


Usted podrá personalizar cómo una API maneja las excepciones escribiendo un filtro de
excepción que implementa la interfaz IExceptionFilter. Se ejecuta un filtro de excepción cuando
un método de controlador HTTP genera una excepción no controlada —que incluye la

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

validación de reglas de negocio y otros tipos


tipos— y se ubica de modo centralizado en la
aplicación. Éste tipo de filtro lo desarrollaremos paso a paso en el laboratorio de la lección.

Como se observa en el siguiente bloque de código, la clase implementa la interfaz


IExcepcionFilter,, que tienen un método OnException para acceder por DI al servicio e inicializar el
constructor de la clase personalizada
zada y referenciada en el parámetro typeof 'ExcepcionesBLL'
personalizado por el programador.

Código

public class ErrControlFilter : IExceptionFilter


{
public void OnException(ExceptionContext
ExceptionContext context)
{
if (context.Exception.
(context.Exception.GetType() == typeof(ExcepcionesBLL))
.
.
.

¡El Aprendizaje Hecho Fácil!

Responses legibles
Como parte de su implementación, enviaremos una respuesta personalizada en formato JSON,
con información clara de la excepción al cliente. Un sistema de información debe ser amigable.

El contenido de la respuesta se puede modificar desde fuera del controlador utilizando una
excepción personalizada y haciendo uso del filtro d de acción. Una vez implementado el código
en el vídeo ¡Aplica ya!, el resultado para verificar la regla de negocio N° 1 debe ser similar a la
siguiente respuesta personalizada:

Código

//CONTROL de la respuesta estructurada al cliente....


var ObjValidar = new
{
Status = 400, //BadRequest...
Titulo = "Regla comercial"
comercial",
Msg = ObjErr.Message
};

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

EL RESULTADO A VISUALIZAR EN EL CLIENTE...


{
"error": [
{
"status": 400,
"titulo": "Regla comercial"
comercial",

"msg": "La estudiante Verónica es nueva!.


El estado "activo" no es válido en la creación de registros.
Favor modificar..."
}
]
}

¡El Aprendizaje Hecho Fácil!

Plus

Como programadores podríamos implementar código para que una vez identificada la creación de un nuevo
estudiante, se asigne el estado como ‘inactivo’ y facilitar el proceso al cliente. La regla de negocio N° 1 indica que
esta asignación sólo la podrá realizar
zar el personal encargado de registrar la matrícula no el de registro de
estudiantes.

Así, este tipo de plus debe ser acordado entre ambas partes y manejado de modo transparente en la
documentación. De esta manera las implementaciones saldrán bien soport
soportadas
adas en futuras auditorías.

Por otra parte, para cada error tipo HTTP o para el que sea necesario, podremos realizar una implementación
genérica, facilitando al cliente la comprensión del mensaje y sugerencia o solución, como lo verá en el vídeo
tutorial de la lección.

Para excepciones que impliquen validaciones, desplegaremos la información al cliente igualmente de modo
personalizado como se observa en la siguiente imagen y que podremos ajustar:

¡El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Tipos de registro
Existen diversas alternativas para filtrar excepciones:
1. En el ActionResult.
2. En el Controller.
3. Globalmente.

Registro en el ActionResult
Permite aplicar una excepción a una acción específica haciendo uso del filtro como atributo.
Sin el filtro tendríamos el siguiente Response: 204 como se observa en la figura. Al revisar en
nuestra tabla de códigos al inicio de la lección encontramos que significa: ”…La petición se ha
completado con éxito pero su respuesta no tiene ningún contenido…”.

Con el filtro obtendremos un Response mucho más informativo o guiador para el cliente como
se observa en la siguiente implementación para un código 404, que hace uso del atributo
ProduceResponseType:

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Código

[HttpGet("{id}")]
[ProducesResponseType(StatusCodes.Status404NotFound)]
(StatusCodes.Status404NotFound)]
public async Task<IActionResult> GetAsynEstuId(int id)
{
...
}

¡El Aprendizaje Hecho Fácil!

Observe la respuesta personalizada e informativa en la sección Response body:

Registro por controlador


Si deseas aplicar el filtro a todos los ActionResult de un controlador se ilustra en el siguiente
ejemplo. Note que el filtro se ha declarado al inicio del controlador API:

Código

namespace API.EscuelaNorte.CA.Controllers
{
[Route("api/[controller]")]
)]
[ApiController]
[ProducesResponseType(StatusCodes.Status404NotFound)]
(StatusCodes.Status404NotFound)]
public class EstudianteController : ControllerBase
{ ...

¡El Aprendizaje Hecho Fácil!

Globalizado
Para aplicar el filtro globalmente a todos los controladores de API web, agregue una instancia
del filtro a la colección de filtros. Los filtros de excepción de la colección se aplican a cualquier
acción del controlador de API web, como lo veremos en el laboratorio
boratorio de la lección.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Realicemos ahora un recorrido visual incluyendo nuestro módulo centralizado para el control de
Excepciones

UML: Diagrama de secuencia

¡El Aprendizaje Hecho Fácil!

Observe la solicitud realizada por el usuario


usuario-cliente
cliente consumiendo el servicio API. El controlador y
su respectivo Endpoint se encarga de hacer la solicitud para traer un estudiante por su ID.

En la capa Core se ejecuta el servicio respectivo EstudianteBLL.cs —pieza


pieza del mecanismo de
desacoplamiento— que forma parte del control de las reglas y validaciones de negocio. Ahora
se llama a través del repositorio en la capa Infraestructura al DbContext responsable de
gestionar en la base de datos el query del request solicitado.

Cuando el dato consultado no se encuentra en la base de datos se devolverá un null al servicio


originador en la capa Core.. Note que existe una validación para valores nulos que forma parte
de la clase class ExcepcionNull (personalizada) y que hereda de la clase nativa Exception.
Exception Se lanza

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

la excepción throw personalizando de esta manera el mensaje al usuario


usuario-cliente,
cliente, gracias al filtro
implementado en la capa Infraestructura a saber, IExceptionFilter.. Este devolverá el resultado
resu
final a la interfaz API indicando en detalle el error HTML.

Laboratorio ¡Aplica ya!

CHECK LIST, Paso a paso

En el vídeo ¡Aplica ya! de esta lección desarrollaremos los siguientes pasos:

Parte I: Completar el CRUD del Controlador API.

1. Completar el resto de métodos API en el Controller del proyecto:


Capa: ->
> Presentación, Controller > Estudiante.

Parte II: Implementar el control personalizado de Excepciones.

1. Implementar como prueba el manejo de excepciones a nivel de un ActionResult o Controlador.


Capa: ->> Presentación, Controlador.
2. Implementar un Filtro para Excepciones personalizado:
Crear una nueva carpeta-folder
folder para el manejo de Excepciones:
Capa: ->> Core, Excepciones.
3. Diseñar las clases necesarias por cada Exception Error a controlar
lar y que heredan de la clase Exception:
Capa: ->> Core, Excepciones.
4. Crear los constructores necesarios.
5. Ajustar el throw para hacer uso de la clase genérica para control de errores:
Capa: -> Core, Servicios.
6. Definir el formato de la excepción:
Agregar una nueva clase:
Capa: ->> Infraestructura, Filtros, ErrControl.cs
7. Instalar el paquete NuGet:
Microsoft.AspNetCore.Mvc.Core
8. Heredar la interfaz IExceptionFilter de > Microsoft.AspNetCore.Mvc.Filters.IExceptionFilter
Capa: ->> Infraestructura, Filtros.
9. Implementar
ntar la interfaz anterior en la clase actual:
Método:
public void OnException(Microsoft.AspNetCore.Mvc.Filters.ExceptionContext context)
10. Referenciamos el tipo —Typeof
Typeof— para la clase ExcepcionBLL.
11. Completar el código del método de control de errores OnException.
12. Registrar el servicio.
Capa: ->> Presentación (API), Program > AddControllers( ).
13. Finaliza implementando una excepción para registros inexistentes.

¡El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

VÍDEO N° 10 , 11 y 12

10 APIs CON C.A. - Excepciones I


11. APIs CON C.A. - Excepciones y Filtros II
12. APIs CON C.A. - Excepciones y filtros III

¡El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Verifique su comprensión

Relacione los elementos:

 Página de excepción del desarrollador.


 200 - 226.
 IExceptionFilter.
 404.
 300 - 308.
 Errores internos reportados por el servidor
servidor.

Este rango de códigos Http indica que la respuesta es


satisfactoria

Muestra la descripción técnica de las excepciones

Famoso código para reportar Not Found!

Rango para indicar que la solicitud ha sido redireccionada

500’s

Esta interfaz se implementa para creación de un filtro


centralizado para las excepciones del programa

Tome un screen y envíe sus respuestas a vuelta de correo para retroalimentación

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Después de esta lección aprenderá a…

1. Conocer los beneficios de los filtros de datos.


2. Desarrollar código para filtrar datos acorde a los requerimientos del cliente.

¡El Aprendizaje Hecho Fácil!

¿Por qué el filtrado?


El filtrado hace referencia a la operación de restringir el conjunto de resultados, de manera que
solo contenga los elementos que cumplen una condición específica. También se conoce como
selección. Esto es fundamental para el perfomance de una aplicación especialmente cuando se
tienen miles de registros.

Filtros en un control ador


Se les conoce también como filtro de acción y corresponden a uno o varios atributos como
parte de los parámetros que se puede aplicar a una acción de controlador (o a un controlador
completo) modificando la forma en que se ejecuta la acción. Se clasif
clasifican
ican como:
1. OutputCache:: este filtro de acción almacena en caché la salida de una acción de
controlador durante un período de tiempo especificado.
2. HandleError:: este filtro de acción controla los errores generados cuando se ejecuta una
acción del controlador.
3. Allow:: este filtro de acción le permite restringir el acceso a un usuario o rol determinado.

Filtros personalizados
También puede crear sus propios filtros de acción personalizados. Por ejemplo, es posible que
desee crear un filtro de acción personalizado para implementar un sistema de autenticación
personalizado. O bien, es posible que desee crear un filtro de acción que modifique los datos
del request devueltos por una acción de controlador. En la lección aplicaremos filtros para
datos. Los demás los desarrollaremos en lecciones posteriores.

Lista de métodos para filtrado


Los métodos del operador de consulta estándar que realizan selecciones se indican en la
siguiente tabla: 28

28
Microsoft

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Sintaxis de la
Nombre del método Descripción expresión de Más información
consulta de C#

Ordena valores en Enumerable.OrderBy


OrderBy orderby
orden ascendente. Queryable.OrderBy

Ordena valores en orderby … Enumerable.OrderByDescending


OrderByDescending
orden descendente. descending Queryable.OrderByDescending

Realiza una
ordenación Enumerable.ThenBy
ThenBy orderby …, …
secundaria en orden Queryable.ThenBy
ascendente.

Realiza una
ordenación orderby …, … Enumerable.ThenByDescending
ThenByDescending
secundaria en orden descending Queryable.ThenByDescending
descendente.

Invierte el orden de
Enumerable.Reverse
Reverse los elementos de una No es aplicable.
Queryable.Reverse
colección.

Por ejemplo, utilizando la cláusula where para filtrar de una matriz aquellas cadenas que tienen
una longitud específica, utilizando comando
comandos de LINQ, que podrá profundizar en el link de la
29
nota.

Código

string[] strPalabras = { "Los"


"Los", "estudiantes", "van", "a", "clase" };

IEnumerable<string>
> ObjQuery = from palabra in strPalabras
where palabra.Length == 3
select palabra;

foreach (string str in ObjQuery)


Console.WriteLine(str);
(str);

¡El Aprendizaje Hecho Fácil!

29
https://docs.microsoft.com/es-es/dotnet/csharp/programming
es/dotnet/csharp/programming-guide/concepts/linq/linq-and
and-strings

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Plus: Requerimientos del cliente

Para el envío de requests con filtros, el cliente decide esto, si se implementa o es es opcional. Así, debemos
establecerlos como Null para que no retornen dato alguno si el cliente no los solicita o utiliza.

Para cantidades de parámetros mayores a cuatro —ver el código siguiente— como estándar y buenas prácticas se
recomienda crear objetos para recibir los parámetros en el método del controlador, como lo aplicaremos en el
laboratorio.

La anterior recomendación centraliza su manejo y evita modificar las firmas de todo el proyecto,
proyecto además de lo
¡extenso que podría ser la refactorización de cada una de estas!

¡El Aprendizaje Hecho Fácil!

Código

NO RECOMENDADO para muchos parámetros...


[HttpGet]
public async Task<IActionResult> GetAsynEstuAll(
string parNombre, string parApellido,
string parEstado, DateTime? parFechaReg)
{

¡CON OBJETOS!
[HttpGet]
public async Task<IActionResult> GetAsynEstuAll(
EstuFiltrosQuery filtroQuery)
{ . . .

¡El Aprendizaje Hecho Fácil!

Observe que los parámetros son manejados haciendo uso de un objeto tipo EstuFiltrosQuery
especializado en realizar la tarea de manera centralizada. Lo verá en el laboratorio.

Binding de datos
El parámetro EstuFiltrosQuery es un Objeto complejo. Configurando
ando los parámetros como
aparecen en el código supracitado, el request irá como cadena query adjunta a la URL. Para
gestionar esto además de los errores de formato reportados por el cliente API que estemos
utilizando, haremos uso de atributos como [FromBody] que se encargará de obtener los
parámetros de la consulta desde la URL. Usted podrá implementarlos en el laboratorio de la
lección. Lo anterior dará como resultado y haciendo uso de la UI de Swagger:

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Este requerimiento fue realizado por el cliente en una de sus reglas de negocio
implementadas y equivale a un Or lógico. La cadena de consulta —QueryString— como aparece
en la imagen, la gestionaremos tomándola desde la URL que apunta al recurso al hacer uso de
la propiedad [FromBody]:

Secuencia de ejecución de un filtro


Los filtros se ejecutan en el siguiente orden prioritario:30

1. Filtros de autorización:
Implementa el atributo IAuthorizationFilter.
Se utilizan para implementar la autenticación y la autorización para las acciones del
controlador.

2. Filtros de acción:
Implementa el atributo IActionFilter.
Contienen lógica que se usa antes y después de que se ejecute una acción de
controlador. Puede usar un filtro de acción, por ejemplo, para modificar los datos que

30
Microsoft.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

devuelve una acción de controlador.

3. Filtros de resultados:
Implementa el atributo IResultFilter.
Contienen lógica que se ejecuta antes y después de ejecutar un resultado. Por ejemplo,
es posible que desee modificar un resultado justo antes de que se represente al cliente.

4. Filtros de excepción:
Implementa el atributo IExceptionFilter.
Es el último tipo de filtro que se ejecuta. Puede usar un filtro de excepciones para
controlar los errores generados por las acciones o resultados del controlador. También
puede usar filtros de excepción para registrar errores.

CHECK LIST, Paso a paso

En el vídeo ¡Aplica ya! de esta lección desarrollaremos los siguientes pasos:


Diseño de un filtro que permita:
Filtrar Estudiantes por nombre, apellidos, estado y fecha de creación.

Técnica de filtrado N° 1: En el controlador.

1. Agregar una nueva carpeta para crear una clase especializada en gestionar los filtros:
Capa: Core > Queries > EstuQuery.
2. Definir en la clase anterior las Propiedades requeridas a encapsular para los filtros necesarios, acorde al
requerimiento o regla.
3. Adicionar el parámetro de tipo objeto complejo del método GetAll( ).
Capa: Presentación, Controller, método GetAll ([FromQuery] Objeto Complejo).
4. Ajustar el parámetro en el resto de las referencias del método GetAll( Objeto Complejo) del proyecto.
Capa: Core, Interfaces, IEstudianteBLL(Objeto Complejo).
Capa: Core, Servicios > EstudianteBLL(Objeto Complejo).
Capa: Presentación, Controller, método GetAll, parámetro en línea await.
5. Implementar los condicionales para atender el request del cliente. Esto es: si el cliente va a filtrar por 1:M
de los parámetros establecidos.

¡El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

VÍDEO N° 13

13. APIs CON C.A. – Filtros: Servicio de filtrado

¡El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Compruebe sus conocimientos

Llene los espacios con el concepto correcto. Pueden sobrar términos o frases:

Frases: IExceptionFilter,
, Reverse, Filtrado, Allow, FromBody.

1. El es clave para el performance de la aplicación y


puede ser de alcance local o global. Es decir, la regla puede ser aplicada
a una sección, área o a toda la organización.

2. Cuando usamos el filtro ordenamos en orden inverso una


lista.

3. Este tipo de filtro, , aplica restricciones de acceso a


un rol predeterminado.

4. Utilizamos para obtener los parámetros de la consulta


desde la URL.

5. Nos facilita centralizar el control de las excepciones.

Tome un screen y envíe sus respuestas a vuelta de correo para retroalimentación


ret

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Después de esta lección aprenderá a…

1. Entender que es un Endpoint en una API.


2. Conocer el estándar OpenAPI.
3. Identificar la estructura básica de una definición de OpenAPI.

¡El Aprendizaje Hecho Fácil!

Los Endpoint
Los Endpoint son los puntos de contacto de la comunicación entre una API y un servidor. O
también, los puntos de entrada que forman parte de la URI. Por ejemplo, hemos creado una API
para la escuela, observe la siguiente URL base:

easytomake.io

Si quiere ir a un recurso debe agregar la palabra clave donde se halla el recurso:

easytomake.io/api/Escuela

En la API objeto de los laboratorios, Escuela corresponde al Endpoint o punto de entrada al


recurso:

> Escuela

Así en la documentación de una API se deben definir de modo claro y preciso los Endpoint. En la
siguiente imagen encontramos el endpoint > Estudiante que despliega los métodos HTTP que
alguno por igual les llaman endpoints:

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Observe que la API debe llevar en la URI base la palabra api/ seguida del Endpoint Estudiante
que corresponden a la ubicación exacta del recurso solicitado, con o sin parámetros. Las
herramientas modernas para la creación de APIs con Swagger permiten configurar los Endpoints
de acuerdo al manejo que necesitemos.
esitemos. Claro, se utilizará o no la palabra api acorde al
enrutamiento seleccionado por los desarrolladores.

Advertencia

Acorde al estándar Open API, la productividad y el rendimiento entre dos sistemas de información que se
comunican mediante una a API, dependen de la claridad y calidad del diseño de los Endpoints.

¡El Aprendizaje Hecho Fácil!

En el mundo de la Internet las organizaciones y el e


e-commerce requieren de estándares para
que todos nos entendamos. Los sistemas de información internos y externos se exponen a
través de sus APIs para que usuarios y clientes puedan interactuar entre aplicaciones.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Plus

UNA API WEB BIEN DISEÑADA

Debe tener como mínimo:


1. Servicio evolutivo: permitir agregar y adicionar nuevas funciones y los usuarios deben detectarlo sin
inconveniente.
2. Independencia de plataformas y tecnologías: Mediante el uso de
protocolos estandarizados y mecanismos comunes para el intercambio de datos o información acordados
previamente.

¡El Aprendizaje Hecho Fácil!

OpenApi: OAS Open Api Specification


Uno de los tantos estándares en la industria de las API es OpenApi.

Es de gran utilidad para el diseño de APIs con calidad. Como comentamos en lecciones
anteriores, una API debe tener una descripción de su interfaz. En la ilustración anterior de la
API Estudiantes la descripción debe ir al frente de cada servicio API, GET, POST, etc.

En particular, OpenAPI puede utilizarse para describir, desarrollar, probar y documentar las API
compatibles con REST, o describirse de mmanera estandarizada o uniforme.

Las propiedades
OpenApi define propiedades que se usan para el diseño de APIs propias. Las propiedades son
agrupadas en objetos. Los siguientes son algunos de los objetos de este estándar: 31

1. Info Object: versión, nombre y demás información requerida de la API.


2. Contact Object: datos de contacto del proveedor de la API.
3. License Object: licencia bajo la cual la API proporciona sus datos.
4. Server Object: nombres del host, estructura del URL y puertos del servidor a través del
cual se dirige la API.
5. Components Object: es encapsulado que puede utilizarse varias veces dentro de una
definición de API.
6. Paths Object: rutas relativas a los puntos finales de la API que se utilizan junto con el
servidor del objeto.
7. Path Item Object: operaciones permitidas para una ruta específica como GET, PUT,
POST, DELETE.
8. Operation Object: especifica, entre otras cosas, los parámetros y las respuestas del
servidor que se esperan de una operación.

31
OpenAPi

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

32
Diagrama de la estructura OpenAPI

Fuent de la imagene: IONOS

En la ilustración se observa la evolución de este estándar:


El estándar OpenApi es compatible con RESTful. Lo utilizaremos en los laboratorios para
documentar y diseñar nuestras APIs, en especial porque ofrece cohesión tanto en la
documentación como en las pruebas. Además es útil para proyectos a cargo de equipos de
desarrollo backend y/o frontend.

En general y como lo indica la documentación de OpenApi, podríamos decir que este estándar,
conocido también como OAS Open Api Specification, define una interfaz estándar,
independiente del idioma para las API HTTP facilitando que tanto los humanos como las
computadoras descubran y comprendan las funcionalidades del servicio sin acceder a código
fuente, documentación o mediante la inspección del tráfico de la red. Cuando nuestra API se
define correctamente, un consumidor puede comprender e interactuar con el servicio remoto y
esto ¡usando una cantidad mínima de lógica de implementación!

32
https://www.openapis.org/

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Las herramientas de generación de documentación pueden uti utilizar


lizar una definición de OpenAPI
para:
1. Mostrar la API,
2. Generar código para servidores y clientes en varios lenguajes de programación,
OpenAPI
3. Realizar casos de prueba y de uso.

Estructura básica de una API con OpenAPI


Una API bien diseñada y acorde a los estándares internacionales del modelo OpenApi debe
contener documentación que describa sus elementos y tener como mínimo:
1. Campo de rutas.
2. Campo de componentes.
3. Campo de WebHooks.

Aunque no se estipula dentro de los componentes mínimos en la documentación el


componente objeto OpenApi Raíz lo hemos incluido en el ejemplo siguiente en formato YAML,
de lectura más entendible :

Código

//OBSERVE LA EXISTENCIA DE VARIOS CAMPOS o SECCIONES: info, server, paths, etc.

openapi: 3.1.0
info:
description: Especificación de API para proyectos académicos.
version: 1.0.0
title: API proyecto de servicios académicos
servers:
- url: 'https://easytomake.io'
- description: 'Ambiente de
e producción de apis Easy To Make'

paths:
#aquí nuestros paths
components:
#componentes reutilizables
security:
#seguridad

¡El Aprendizaje Hecho Fácil!

En el ejemplo son secciones: openapi, info, servers, paths, components, security entre otras.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Campo de rutas
Corresponde a las expresiones de plantilla
plantilla,, delimitadas por llaves ({}), para marcar una sección
de una ruta URL como reemplazable mediante parámetros de ruta. Las rutas definen el acceso a
los endpoint de los recursos URI mediante el uso de los verbos HTTP descritos en la lección
anterior para APIs con RESTful. En el siguiente ejemplo la ruta nos lleva al endpoint Estudiantes:

Código

//LA RUTA:
Estudiantes / {Id}

GET api/Estudiantes/{id}

¡El Aprendizaje Hecho Fácil!

En el ejemplo se ha diseñado la ruta al recurso endpoint 'Estudiantes' acompañado de un


parámetro 'id'. Así y como parte documental usando el estándar OpenApi para diseñar la ruta
anterior excluyendo el parámetro, tendríamos lo siguiente en formato JSON (se estudiará más
adelante):

Código

{
"/Estudiantes": {
"get": {
"description": "Acceso a la lista de todos los estudiantes",
"responses": {
"200": {
"description": "Toda la lista de estudiantes.",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Estudiantes"
}
.
.
.

¡El Aprendizaje Hecho Fácil!

La operación anterior puede tener además la sección de parámetros que son pasados a través
de la ruta así:

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Código

paths:
/Estudiantes/{ID}:
get:
summary: Retorna un estudiante por su ID
parameters:
- name: ID
in: path
required: true
description: Parameter description in CommonMark or HTML.
schema:
type : integer
format: int64
minimum: 1
responses:
'200':
description: OK

¡El Aprendizaje Hecho Fácil!

Campo de componentes: resumen


Para el uso de componentes definiremos las secciones a implementar y reutilizar en nuestro
desarrollo de la API. El objeto componente se conforma por otros objetos reutilizables en la
API. Citamos la tabla original expuesta en el sitio del estándar OpenApi y hemos dejado los link
originales de la columna Tipos para profundización por parte del estudiante: spec.openapis.org

Nombre del Tipo Descripción


campo
schemas Map[string, Schema Object
Object] Un objeto para contener objetos de
esquema reutilizables .

responses Map[string, Response Un objeto para contener objetos de


Object | Reference Object
Object] respuesta reutilizables .

parameters Map[string, Parameter Un objeto para contener objetos de


Object | Reference Object
Object] parámetros reutilizables

examples Map[string, Example Object | Reference Un objeto para contener objetos de


Object] ejemplo reutilizables .

requestBodies Map[string, Request Body Un objeto para contener objetos de cuerpo de


Object | Reference Object
Object] solicitud reutilizables .

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

headers Map[string, Header Object | Reference Un objeto para contener objetos de


Object] encabezado reutilizables .

securitySchemes Map[string, Security Scheme Un objeto para contener objetos de esquema de


Object | Reference Object
Object] seguridad reutilizables .
links Map[string, Link Object | Reference Un objeto para contener objetos de
Object] enlace reutilizables .
callbacks Map[string, Callback Object | Reference Un objeto para contener objetos de devolución de
Object] llamada reutilizables .
pathItems Map[string, Path Item Un objeto para contener un objeto de elemento
Object | Reference Object
Object] de ruta reutilizable .

Los componentes sirven como contenedor para varias definiciones reutilizables


reutilizables:: esquemas
(modelos de datos), parámetros, respuestas, ejemplos y otros. Una vez revisado el cuadro
resumen anterior, en el siguiente ejemplo se enumeran las subsecciones disponibles. Todas las
subsecciones son opcionales de acuerdo a lo expuesto en OpenA
OpenApi:

Código

components:
# Reusable schemas (data models)
schemas:
...
# Reusable path, query, header and cookie parameters
parameters:
...
# Security scheme definitions (see Authentication)
securitySchemes:
...
# Reusable request bodies
requestBodies:
...
# Reusable responses, such as 401 Unauthorized or 400 Bad Request
responses:
...
# Reusable response headers
headers:
...
# Reusable examples
examples:
...
# Reusable links
links:
...
# Reusable callbacks
callbacks:
...

¡El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Son ejemplos de nombres válidos:


● Estudiantes
● Nuevo_Estudiante
● easytomake.ejemplo.Estudiantes
● 401-Unauthorized

Objeto Paths
Contiene las rutas relativas a los puntos finales o endpoints individuales con sus operaciones.
La ruta se agrega a la URL desde el Server Object para construir la URL completa.

Campo de WebHooks, Callback


Para ilustrarlo, tenemos estos casos:
1. Cuando realizamos un retiro bancario, los sistemas de información de estas
corporaciones disparan un mensaje de texto SMS o un correo indicando que se ha
realizado un retiro de la cuenta.
2. Cuando realizamos una suscripción se dispara un WebHook que notifica al usuario y a la
organización de la nueva suscripción.
3. Cuando se realiza una compra en su sitio e
e-commerce, un WebHook notificará a la
gerencia de la nueva venta.
4. Cuando solicitamos información a través de un chat como Whatsapp, Telegram,
Messenger, de modo automático nos llega una respuesta predefinida!… WebHook se ha
puesto en acción.

A las notificaciones anteriores se les conoce en el mundo de las API como devolución de
llamada o callback.

WebHooks (ganchos)

Mensajería automatizada que se dispara cuando ocurre un evento. Es el guardián de cualquier evento en
Internet…. y lo notifica!

A diferencia de las APIs que requieren solicitud/respuesta, los WebHooks no requieren solicitud.

¡El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Notificación de llamadas o eventos Websocket

Con este mecanismo en las especificaciones de OpenAPI 3.x en adelante, se puede definir devoluciones de llamada
—solicitudes
solicitudes asincrónicas y fuera de banda
banda— que nuestros servicios enviarán a algún otro servicio en respuesta a
ciertos eventos. Esto nos ayuda a mmejorar
ejorar el flujo de trabajo que ofrece el diseño de la API a los clientes.

WebHook técnicamente: solicitudes HTTP entrantes que responden a algún evento o estímulo externo.

¡El Aprendizaje Hecho Fácil!

Ejemplo de una notificación


Cada vez que un estudiante se registra en easytomake.net un WebHook previamente
programado se dispara desde su API interna. Usted no necesita estar preguntando o
consultando si hubo suscripciones en el día.

Primero puede verificar si el sistema admite ese evento yendo a la operación “Listar eventos”
(GET / webhooks / events). Si hay un evento ““create”” para el recurso “Estudiante”, puede ir a la
operación “Crear un webhook” (POST / webhooks) y crearlo con el rrecurso,
ecurso, evento y URL
deseados donde la solicitud de devolución de llamada POST se enviará cada vez que se cree el
usuario. Los parámetros opcionales para los webhooks son secretos y activos y se explican en el
esquema del cuerpo de la solicitud en la opera
operación “Crear un webhook”. La siguiente sería la
operación registrada dentro de nuestra API:

Código

paths:
/registros:
post:
summary: Suscrito a un webhook
requestBody:

callbacks: # Definición de Callback
myEvent: # Nombre del evento
'{$request.body#/callbackUrl}'
'{$request.body#/callbackUrl}': # La URL para mostrar
# información del evento
post:
requestBody: # Contenido del mensaje
required: true
content:
application/json:
schema:
type:
: object
properties:
message:
type
type: string

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

example: Felicitaciones. ¡Se ha registrado un estudiante!


required:
- message
responses: # Respuestas esperadas al mensaje de devolución de llamada
'200'
'200':
description: Si la operación fue exitosa

¡El Aprendizaje Hecho Fácil!

Solicitudes y respuestas
O también Request Body y Responses
Responses,
Si una operación envía un cuerpo de solicitud, use la palabra clave requestBody para describir el
contenido del cuerpo y el tipo de medio así:

Código

paths:
/Estudiantes:
post:
summary: Crear un estudiante
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
nombreEstudiante:
type: string
responses:
'201':
description: ¡Estudiante Creado!

¡El Aprendizaje Hecho Fácil!

Para cada operación, puede definir posibles códigos de estado, como 200 OK o 404 Not Found,
y el cuerpo de la respuesta schema. El formato OpenAPI para las respuestas sería:

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Código

paths:
/Estudiantes/{ID}:
get:
summary: Retorna un estudiante por su ID.
parameters:
- name: ID
in: path
required: true
description: ID del estudiante a retornar.
schema:
type: integer
format: int64
minimum: 1
responses:
'200':
description: Un objeto estudiante.
content:
application/json:
schema:
type: object
properties:
ID:
type:
: integer
format: int64
example: 4
nombreEstudiante:
type: string
example: Veronica Brown
'400':
description: El ID no es válido (no es un número).
'404':
description: El Id solicitado no se encontró.
default:
description: Error inesperado. Comuníquese con el administrador.

¡El Aprendizaje Hecho Fácil!

En resumen
La documentación API debe tener:
1. Explicación de ejecución de la API.
2. Información para autenticación de usuarios.
3. Instrucciones para el uso de todos los endpoint.
4. Ejemplos ilustrativos de su uso. Sería estupendo hacer uso de vídeo tutoriales cortos y
claros.
5. Algo de código ilustrativo.

Esto es: Buena experiencia de usuario (UX)


(UX),, además del ahorro de horas atendiendo
solicitudes por soporte.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Iniciaremos con la documentación básica o mínima para una API sencilla. Generalmente generar
genera
la documentación se hace:
1. De modo manual, vídeo parte I.
2. De modo automatizado, vídeos II, III.

Documentación automatizada

Plus

Existen muchas empresas que prestan el servicio de documentación automatizada. Esta pequeña inversión facilita
grandemente minimizar el desgaste del equipo de trabajo y el ROI en especial para grandes proyectos
comerciales. Dejamos algunas como referencia:

1. StopLight
Proporcione una experiencia de desarrollad
desarrollador
or de primer nivel para consumidores internos y externos
generada automáticamente a partir de sus archivos OpenAPI.
2. Postman
Utilice la herramienta de documentación de la API de Postman p para
ara generar documentación hermosa y
legible por máquina, para su API, y mantenerla actualizada automáticamente.
3. ApiDoc
Una característica útil proporcionada por apiDoc es la capacidad de mantener la documentación de
todas
odas las versiones anteriores y la última versión de la API. Esto hace posible comparar la versión de un
método con su predecesor. El desarrollador de frontend puede simplemente ver qué ha cambiado y
actualizar su código en consecuencia.
4. Slate
Permita que sus usuarios actualicen su documentación por usted : de forma predeterminada, su
documentación generada por Slate se aloja en un repositorio público de GitHub. Esto no solo significa
que obtiene alojamiento to gratuito para sus documentos con GitHub Pages, sino que también facilita que
otros desarrolladores realicen solicitudes de extracción a sus documentos si encuentran errores
tipográficos u otros problemas. Por supuesto, si no desea utilizar GitHub, tambiénén puede alojar sus
documentos en otro lugar.
5. Swagger
Swagger elimina el trabajo manual de la documentación de API, con una variedad de soluciones para
generar, visualizar y mantener document
documentos de API.

¡El Aprendizaje Hecho Fácil!

33
Documentación en .NET Core
Los archivos de origen de C# pueden tener comentarios estructurados que generan
documentación de API para los tipos definidos en esos archivos. El compilador de C# genera un
archivo XML que contiene datos estructurados que representan los comentarios y las firmas de

33
Microsoft.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

API. Otras herramientas pueden procesar esa salida XML para crear documentación legible en
forma de páginas web o archivos PDF, por ejemplo.

Este proceso proporciona muchas ventajas para agregar documentación de API en el código:
● El compilador de C# combina la estructura del código de C# con el texto de los
comentarios en un único documento XML.
● El compilador de C# comprueba que los comentarios coinciden con las firmas de API
para las etiquetas pertinentes.
● Las herramientas que procesan los archivos de documentación XML pueden definir
elementos y atributos XML específicos de esas herramientas.

Como parte de las herramientas para crear salida XML en .NET Core tenemos:
● DocFX: DocFX es un generador de documentación de API para .NET, que actualmente
admite C#, Visual Basic y F#. También permite personalizar la documentación de
referencia generada. DocFX compila un sitio web HTML estático a partir del código
fuente y los archivos Markdown. Además, DocFX proporciona la flexibilidad para
personalizar el diseño y el estilo de su sitio web a través de plantillas. También puede
crear plantillas personalizadas.
● Sandcastle: las herramientas de Sandcastle crean archivos de ayuda para bibliotecas de
clases administradas que contienen páginas de referencia tanto conceptuales como de
API. Las herramientas de Sandcastle se basan en la línea de comandos y no tienen front-
end de GUI, características de administración de proyectos ni proceso de compilación
automatizado. El Generador de archivos de ayuda de Sandcastle proporciona
herramientas independientes basadas en GUI y la línea de comandos para crear un
archivo de ayuda de forma automatizada. También está disponible un paquete de
integración de Visual Studio para que los proyectos de ayuda se puedan crear y
administrar completamente desde Visual Studio.
● Doxygen: Doxygen genera un explorador de documentación en línea (en HTML) o un
manual de referencia fuera de línea (en LaTeX) a partir de un conjunto de archivos de
código fuente documentados. También se admite la generación de resultados en RTF
(MS Word), PostScript, PDF con hipervínculo, HTML comprimido, DocBook y páginas
man de Unix. Puede configurar Doxygen para extraer la estructura de código de los
archivos de código fuente no documentados.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Después de esta lección aprenderá a…

● Conocer servicios de automatización.


● Implementar la documentación de nuestra API paso a paso con .NET Core.
● Diseñar código para los servicios de Documentación API en el contenedor.
● Exportar documentación a Swagger
● Diseñar un documento soporte PDF.

¡El Aprendizaje Hecho Fácil!

Saliendo a producción
En este punto la API funciona en nuestra máquina pero cliente requiere muestras, pruebas o
adelanto del desarrollo. Para hacerlo posible debemos como mínimo hacer entrega de
la Documentación API. Lo anterior implica que el cliente debe conocer el contrato de su API.
Esto lo diseñan algunos programadores haciendo
iendo uso de editores de texto populares, pero la
industria estandarizó la documentación para hacer su entrega al cliente o los desarrolladores
como lo veremos en el siguiente vídeo.

Plus

Haga valer su trabajo profesional

Hay que trabajar duro para implementar una API. Por muy funcional que resulte si los clientes o desarrolladores
no entienden cómo hacer uso de sus servicios de nada vale el esfuerzo.

La documentación API es el manual de usuario, la brújula para que nuestros clientes se familiaricen
familia con sus
servicios.

¡El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Aspecto final de la
documentación básica
API en .NET Core

Observe parte del


encabezado con los link
para conocer los
términos de servicio
como link externo, sitio
web de autor, términos
de la licencia API
(Open), el esquema en
formato json, la
descripción de los
endpoint, los servicios de autenticación y autorización (token), entre otros.

La documentación haciendo uso de la herramienta online Swagger la aprenderá en el último


vídeo de esta lección.

Laboratorio ¡Aplica ya!


Implementando la documentación con Swagger

CHECK LIST, Paso a paso

Parte I: Generando la documentación.

1. Instalar el paquete NuGet (ya viene cargado en la plantilla .Net Core API) > Swashbuckle.AspNetCore:
Capa: Presentación, Dependencias
2. Verificar el registro del servicio:
Capa: Presentación, Program.cs.
Configurar el pipeline HTTP Request
3. Implementación del código y registro del servicio de documentación:
Capa: Presentación, Program.cs.
4. Habilitar en Compilación del proyecto API, la salida de documentación XML.
Capa: Presentación > Propiedades > Compilar.
5. Validar el despliegue inicial de la documentación:
https://localhost:1234/swagger/v1/swagger.json
6. Guardar como, Descargar o exportar el archivo JSON de la documentación con Swagger.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

7. Importar el archivo JSON de la documentación a Swagger.


Swagger > editor swagger.io.
8. Documentar nuestros métodos de cada endpoint agregando la sección > summary en el encabezado de
cada uno.
9. Completar el código para documen
documentación,
tación, links externos, tutoriales o instructivo online desde la API.
10. Generar e importar el último archivo JSON de la documentación a Swagger.
Swagger > editor swagger.io.

¡El Aprendizaje Hecho Fácil!

Material adjunto

Documentación Externa - Escuela Norte API.

El esquema de la documentación API podrá descargarlo una vez finalice los siguientes laboratorios desde el link
superior de us API ‘Swagger.json’

¡El Aprendizaje Hecho Fácil!

VÍDEOS N° 14, 15 y 16

14. APIs CON C.A. - Documentación API I


15. APIs CON C.A. - Documentación API II
16. APIs CON C.A. - Documentación API III

¡El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Reafirme sus conocimientos

Marque solo las respuesta correctas:

Debemos agregar el nombre del recurso en la URI de una API como por
ejemplo: easytomake.io/api/
easytomake.io/api/Escuela.aspx

Para el estándar Open API, la productividad y el rendimiento entre dos


sistemas de información que se comunican mediante una API, dependen de la
claridad y calidad del diseño de los Endpoints.

El servicio evolutivo y la independencia de plataformas, es señal


s de un
buen diseño API.

OpenApi estandariza la descripción de una API compatible con REST.

Los campos de rutas y WebHook son lo mínimo para describir los elementos
de una API con el estándar OpenAPI

Un campo de ruta define el acceso a los endpoin


endpointt de los recursos URI
mediante el uso de verbos HTTP

Una devolución de llamadas o WebHook (ganchos) equivale a un callback

Los WebHooks requieren solicitud o request.

La documentación API no requiere información de autenticación de


usuarios. Solo Ejemplos ilustrativos de su uso, explicación de ejecución y
cómo usar los endpoint.

El manual de usuario de una API equivale a la documentación.

Tome un screen y envíe sus respuestas a vuelta de correo para retroalimentación

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
PARTE
Diseño. Series desde cero. https://vladodotnet.wordpress.com/
4
PARTE IV: Seguridad JWT
JWT,, UoW,
Deploying
Después de esta lección aprenderá a…

● Distinguir e implementar la autenticación y autorización API.


● Conocer qué es un Token.
● Identificar los conceptos relacionados con JWT, campos y estructura.
● Diseñar la generación de un Token para la API Escuela Norte.
● Modelar la validación y autorización para creación de usuarios API.
● Aplicar siguiendo el paso a paso de los vídeos ¡Aplica ya!

¡El Aprendizaje Hecho Fácil!

¿Qué es autenticar?
Haremos uso de la siguiente definición:

Autenticación

“Es el acto o proceso de confirmar que algo (o alguien) es quien dice ser.

A la parte que se identifica se le llama probador.


A la parte que comprueba la identidad se la llama verificador.

¡El Aprendizaje Hecho Fácil!

Para ilustrarlo:
El probador es nuestro cliente-usuario
usuario API que necesita acceder a un endpoint de la API Escuela
Norte. El verificador es nuestro servicio implementado para realizar la autenticación
ción
comprobando que el que va a accede sea un usuario que cumpla estas condiciones:
condiciones
1. Que esté registrado y sus credenciales sean válidas.
2. Tenga permisos o rol para hacer uso de los recursos y servicios prestados por la API.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

“Para poder tener autenticación es necesaria —como condición previa— la existencia de


identidades biunívocamente de tal forma que se permita la identificación de credenciales y el
usuario.“ 34

Ahora pasemos a conocer el proceso de autorización y seguridad API.

¿Qué es un Token?
Referencia,identificador

Un token de software es un artefacto informático de seguridad digital para sistemas de


autenticación de dos factores.

La tokenización es el proceso de reemplazar datos confidenciales con símbolos de


identificación únicos que retienen toda la información esencial sobre los datos sin comprometer
la seguridad.

“Un token JWT generalmente contiene:



Un cuerpo con información sobre el usuario autenticado (identificador de sujeto,
reclamos, etc.),

El emisor del token,

La audiencia (destinatario) al que está destinado el token y

Un tiempo de vencimiento (después del cual el token es inválido).

“Un token también contiene una firma criptográfica que es generada por una clave privada
conocida solo por el servidor de autenticación” 35

En la ilustración se resume el proceso de solicitudes y respuestas con el token generado por la


API y relacionado en cada petición subsiguiente del cliente como parte del encabezado del
mensaje que nuevamente se valida su autenticidad.

34
Wiky.
35
Microsoft.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

El usuario solicita los servicios API (POST: Login). El servidor valida y marca como true la
autenticación. De lo contrario indicará al usuario que su token ha expirado y genera un nuevo
TOKEN (payload). El usuario envía su request con el Token en un encabezado. El servidor
comprueba las credenciales y valida el token para su envío. Ahora se procede a asegurar el
recurso al usuario, quien obtendrá los servicios solicitados hasta que el token asignado se venza.
De ser así, el servidor requerirá una nueva autenticación para generar un nuevo token.

¿Por qué JWT?


El almacenamiento de credenciales y la seguridad de Internet son variables críticas a la hora de
transmitir datos o información entre clientes y servidores. El estándar JWT permite garantizar
que la información transmitida no ha sido modificada en el recorrido. Esta validación se logra
de modo local —en el cliente gracias a este estándar— haciendo uso de un Token.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Los JWT se pueden firmar usando una SecretKey con el algoritmo criptográfico HMAC36 o un
par de claves pública / privada usando RSA37 o ECDSA38.

El token es realmente una cadena de texto (en la figura strToken usado en el laboratorio de la
lección) que tiene tres partes codificadas en Base6439, cada una de ellas separadas por un punto,
como se ve en la imagen del token que desarrollaremos en el laboratorio de la lección:

Las partes o estructura de un token


JWT ha diseñado el estándar con 3 partes que conforman el token:

Header
El encabezado generalmente consta de dos partes:
a. El tipo de token, que en este caso es de tipo JWT, y
b. El algoritmo de firma que se utiliza, como HMAC SHA256 o RSA.
La cadena de texto generada en formato JSON está codificado en Base64Url para formar la
primera parte del JWT.

Observe el siguiente ejemplo de un encabezado JWT:

36
En la criptografía, un HMAC (a veces expandido como código de autentificación de mensajes en clave-
hash o código de autenticación de mensaje basado en hash) es una construcción específica para calcular
un código de autentificación de mensaje (MAC) que implica una función hash criptográfica en combinación
con una llave criptográfica secreta. Wiky.
37
En criptografía, RSA (Rivest, Shamir y Adleman) es un sistema criptográfico de clave
pública desarrollado en 1979, que utiliza factorización de números enteros. Es el primer y más
utilizado algoritmo de este tipo y es válido tanto para cifrar como para firmar digitalmente.
38
El algoritmo de firma digital de curva elíptica, o ECDSA, es uno de los algoritmos de
cifrado de criptografía de clave pública más complejos. Utiliza la criptografía de curva elíptica muy
usada para la creación de números pseudoaleatorios, firmas digitales y más.
39
Base64 es un algoritmo de codificación que le permite transformar cualquier carácter en un alfabeto que
consta de letras latinas, dígitos, más y barra diagonal. Gracias a él, puede convertir caracteres chinos,
emojis e incluso imágenes en una cadena "legible", que se puede guardar o transferir a cualquier lugar.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Código

{
"alg": "HS256", "typ": "JWT"
}

¡El Aprendizaje Hecho Fácil!

Payloads, Carga Útil


O contenido del mensaje. La segunda parte del token es la carga útil, que contiene las
notificaciones y la información del usuario como nombre, correo, idioma, etc. Como ejemplo de
un payload (se pronuncia péiloud) tenemos el usado en el laboratorio de esta lección:

Código

{
user_id: 777,
account_id: 666,
email: '[email protected]',
full_name: 'Veronica Brown',
default_language: 'en_US'
}

¡El Aprendizaje Hecho Fácil!

El campo payload de JSON Web Token contiene la información real que se transmitirá por la
aplicación.. Aquí se definen algunos estándares que determinan qué datos se transmiten y
cómo. La información se proporciona como pares key/value (clave-valor).

Las claves del Claim (reclamación, requerimiento)


Las claves se denominan claims en JWT. Hay tres tipos diferentes de claims:

● Los claims registrados son los que figuran en el JSON Web Token Claim Register de la
IANA40 y cuyo propósito se establece en un estándar. Algunos ejemplos son el emisor

40
Internet
et Assigned Numbers Authority
Authority:: La coordinación global de la raíz dns, el direccionamiento IP y
otros recursos de protocolo de Internet. Específicamente, asignan y mantienen códigos y sistemas de
numeración únicos que se utilizan en los estándares técnicos ("protocolos") que impulsan Internet.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

del token (iss, de issuer),


), el dominio de destin
destino (aud, de audience)) y el tiempo de
vencimiento (exp, de expiration time
time). Se utilizan nombres de claim cortos para abreviar
el token lo máximo posible.
● Los claims públicos pueden definirse a voluntad, ya que no están sujetos a restricciones.
Para que no se produzcan conflictos en la semántica de las claves, es necesario registrar
los claims públicamente en el JSON Web Token Claim Register de la IANA o asignarles
nombres que no puedan coincidir.
● Los claims privados están destinados a los datos que intercam
intercambiamos
biamos especialmente
con nuestras propias aplicaciones. Si bien los claims públicos contienen información
como nombre o correo electrónico
electrónico, los claims privados son más concretos.
concretos Por ejemplo,
suelen incluir datos como identificación de usuario o nombre de departamento.
departamento Al
nombrarlos, es importante asegurarse de que no vayan a entrar en conflicto con
ningún claim registrado o público. 41

Advertencia

Payload malicioso

El phishing (suplantación de identidad) es el método más común para hacer uso de un payload y descargar
archivos maliciosos, sea en el encabezado de un correo, secuestro de la DNS, SMS o VoIP
VoIP42.
Generalmente se diseñan en sistemas operativos Kali Linux con extensión .apk.

Por tal motivo, las APIs seguras deben hacer uso de herramientas ro
robustas,
bustas, probadas, verificadas por la
comunidad y frameworks reconocidos internacionalmente como es el caso de .Net Core framework.

¡El Aprendizaje Hecho Fácil!

Verify Signature, Firma


Para crear la parte de la firma, debe tomar el encabezado codificado, la carga útil codificada,
una clave secreta, el algoritmo especificado en el encabezado, y firmarlo.

Por ejemplo, si desea utilizar el algoritmo HMAC SHA256, la firma se creará de la siguiente
manera:

41
Microsoft.
42
El Protocolo de Voz sobre Internet (VoIP), también llamado telefonía IP,
, es un método y grupo de
tecnologías para la entrega de comunicaciones de voz y sesiones multimedia a través de redes de Protocolo
de Internet (IP), como Internet.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Código

{
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
}

¡El Aprendizaje Hecho Fácil!

La firma se usa para verificar que el mensaje no se haya modificado en el camino. En el caso de
los tokens firmados con una clave privada, también puede verificar que el remitente del JWT es
quien dice ser. El resultado son tres (3) cadenas de URL Base64 separadas por puntos que se
pueden pasar fácilmente en entornos HTML y HTTP, mientras que son más compactas en
comparación con estándares basados en XML como SAML.

Hemos modificado, cambiado, editado de la siguiente firma un solo carácter y este es el


resultado: una firma corrupta que será rechazada por el sistema de seg
seguridad:

Código

"{\"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name\":\"Cesar Brown\
\",
\"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress\"
:\"[email protected]\",\"http://schemas.microsoft.com/ws/2008/06/identity/claims/role
"http://schemas.microsoft.com/ws/2008/06/identity/claims/role\
"http://schemas.microsoft.com/ws/2008/06/identity/claims/role
":\"Keymaster\",\"nbf\":1641304M
":1641304M\f\u000b\b�^\u001c\b��M�\fL�
\rL��\u000b\b�\\�Ȏ��\u001du001d\u001d\u001c\u001c΋��\u001b��[\u001a\u001b�� ��\u000e�̎ MKȋ\b�]
Y\b���\u001
d\u001d\u001c\u001c΋��\u001b
u001b��[\u001a\u001b��\u000e�̎ MKȟ"

¡El Aprendizaje Hecho Fácil!

En una aproximación inicial y como ejemplo real de nuestra API Escuela Norte, tenemos el
siguiente token:

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Código

HEADER
{
"alg": "HS256",
"typ": "JWT"
}

PAYLOAD : DATOS
{
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name": "Cesar Brown",
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress": "[email protected]",
"[email protected]"
"http://schemas.microsoft.com/ws/2008/06/identity/claim
"http://schemas.microsoft.com/ws/2008/06/identity/claims/role": "Keymaster",
"nbf": 1641305140,
"exp": 1641305260,
"iss": "https://localhost:7295/"
"https://localhost:7295/",
"aud": "https://localhost:7295/"
}

VERIFICACIÓN DE LA FIRMA , SIGNATURE


HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),

your-256-bit-secret

) secret base64 encoded

TOKEN
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ
IkpXVCJ9
.eyJodHRwOi8vc2NoZW1hcy54bWxzb
bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW
uYW1lIjoiQ2VzYXIgQ
nJvd24iLCJodHRwOi8vc2NoZW1hcy54
54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy
NsYWltcy9lbWFpbGFkZHJ
lc3MiOiJkYmFjZXNhckBvdXRsb29rLmNvbSIsImh
rLmNvbSIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3
3MvMjAwOC8wNi9pZ
GVudGl0eS9jbGFpbXMvcm9sZSI6IktleW
IktleW1hc3RlciIsIm5iZiI6MTY0MTMwNTE0MCwiZXhwIjoxNjQxMzA
MCwiZXhwIjoxNjQxMzA1MjYwLCJpc3M
iOiJodHRwczovL2xvY2FsaG9zdDo3Mjk
Mjk1LyIsImF1ZCI6Imh0dHBzOi8vbG9jYWxob3N0OjcyOTUvIn
OjcyOTUvIn0
.ky1mAo4CAUYxazBifiJQpwxlNDk_K
CAUYxazBifiJQpwxlNDk_K3uMGaXhgeBssvs

¡El Aprendizaje Hecho Fácil!

Error 401
Si el usuario cliente no está autorizado y debe solicitar su token sea por ser primera vez o por
vencimiento, se desplegará un error de tipo response HTTP 401 como se observa en la imagen:

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Cuando las credenciales de autenticación del usuario no corresponden a las digitadas se activa
un error HTTP 404 como se observa en la imagen, para nuestro caso, con el mensaje
personalizado visto en el laboratorio de la lección:

Base64Url
Namespace:Microsoft.IdentityModel.Tokens

Convierte la cadena especificada, que codifica datos binarios como dígitos base64-url, en una
matriz de enteros sin signo de 8 bits equivalente. Los esquemas de codificación Base64 son
comúnmente usados cuando se necesita codificar datos binarios para que sean almacenados y
transferidos sobre un medio diseñado para tratar con datos textuales. Esto es para asegurar que
los datos se mantienen intactos y sin modificaciones durante la transmisión. 43

43
Mozilla.org

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

La solicitud y respuesta con JWT


En resumen de todo lo anterior, la siguiente ilustración muestra en detalle el proceso de
seguridad cuando un usuario-cliente realiza una petición API:

FUENTE: devopsschool.com.

Observe el proceso de validación de autenticación y finalmente autorización de acceso a los


recursos del servicio API en el servidor.

En el diagrama UML de secuencia de esta lección, encontramos una diversidad de métodos


manejados por la clase que implementaremos, KeyApiController, con tareas muy especiales
como la validación de las credenciales del cliente-usuario y generación del Token que será
remitido como parte del response.

Una vez diseñado el servicio para la generación de un Token, el proceso y resultado sería el
siguiente con el nuevo endpoint KeyAPI para el manejo de la seguridad de nuestra API, tarea a
desarrollar en el siguiente laboratorio:

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

UML: Diagrama de secuencia

¡El Aprendizaje Hecho Fácil!

Explicación
El cliente realiza la solicitud haciendo uso de la API. Se ejecuta el servicio para generar el token,
IConfiguration.. Ahora el control se pasa a la capa de seguridad o clase
clase-objeto Login para
recoger las credenciales del usuario, haciendo uso del endpoint Http Post.. El objeto token ahora
debe validar o autenticar las credenciales suministradas por el cliente contra el repositorio o
fuente de datos quien devolverá true o false. Si es true se procede a generar el token para ser
enviado al cliente.

Por supuesto,
to, ya hemos diseñado previamente la funcionalidad de la capa y su objeto token
como se debe observar en el despliegue de los endpoint, implementando el método Post del
endpoint KeyAPI:

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Ahora el cliente haciendo uso del endpoint implementado en la API, procede a enviar sus
credenciales que corresponden al parámetros de validación de Login, a través de la URL que
apunta al endpoint y método GET como se observa en la imagen:

Obtenemos entonces la respuesta API a la solicitud del usuario una vez generado
el Token dentro del Response body como se nota en la imagen:

Ahora el usuario una vez verificadas sus credenciales y generado su token podrá acceder a los
servicios API con el token generado, asegurando su operación.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Plus: contrarrestando la vulnerabilidad

44
Todo sistema propende a la Entropía. En el link a pie de página encontrará recomendaciones para enfrentar
potenciales fallos con JWT.

¡El Aprendizaje Hecho Fácil!

Laboratorio ¡Aplica ya!

Material adjunto

El siguiente material será utilizado en el laboratorio:

❖ Guía de bolsillo JWT


JWT-Handbook-v0
v0 , archivo adjunto a la lección para
consultas.

❖ Código para el servicio: Copiar el siguiente código para agilidad del


proceso, pero puede editarlo paso a paso.
Se utilizará en el punto 3, Parte I, del siguiente paso a paso.

Recomendación: Intente digitarlo y comprender su lógica.

// SEGURIDAD...
builder.Services.AddAuthentication(auth =>
{
auth.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
auth.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(opt =>
{
opt.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = builder.Configuration["JWT:Issuer"],
ValidAudience = builder.Configuration["JWT:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(builder.Configuration["JWT:Key"]))
};
});

¡El Aprendizaje Hecho Fácil!

44
https://connect2id.com/products/nimbus
https://connect2id.com/products/nimbus-jose-jwt/vulnerabilities

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Los siguientes diagramas muestran el paso a paso, código y generación de un Token


El proceso se irá explicando y desarrollando en el vídeo tutorial. Observe de modo mucho más
detallado, las partes que conforman el TOKEN
TOKEN, es decir, la entrega
ntrega del TOKEN al usuario y
autorización para acceder a los recursos del servidor.

UML: Diagrama de secuencia

¡El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

UML: Diagrama de secuencia

¡El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

UML: Diagrama de secuencia

¡El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

UML: Diagrama de secuencia

¡El Aprendizaje Hecho Fácil!

Los anteriores diagramass de secuencia registran el proceso de implementación para la


autenticación de credenciales de un usuario quien solicita el acceso a los servicios API. Por
supuesto, antes de generar un Token es indispensable este primer paso.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

CHECK LIST, Paso a paso

En el vídeo ¡Aplica ya! de esta lección desarrollaremos los siguientes pasos:

Parte I : Implementando la seguridad


1. Configurar un nuevo nodo para Autenticación:
Capa: Presentación > Appsetting.json
Digitar el código respectivo explicado en el vídeo.
2. Agregar el NuGet > Microsoft.AspNetCore.Authentication.JwtBearer
3. Configuramos el servicio middleware y definimos los schemas:
Capa: Presentación > Program.cs.
Copiar o editar el código anexo arriba, caja ‘Material adjunto’.
4. Declara el uso del servicio de autenticación > UseAuthentication();
Capa: Presentación > Program.cs.

Parte II : La autenticación
El cliente debe validar sus credenciales en nuestra app y solicitar
un token. Nuestra API debe generar el token que formará parte del Header en
el request del cliente > Hedear > Key.

1. Implementar una clase que gestione la autenticación del usuario-cliente,


usuario
generando una nueva entidad en el modelo
Capa: Core, Entidades > LoginUser
2. Implementar una clase API que gestione la autenticació
autenticación:
Capa: Presentación, Controller

Parte III : El Token

Implementar el proceso de generar token.


1. Generar el método que gestione el Header del token y el schema:
Capa: Presentación, Controller > KeyTokenAPI > TokenGenerado();
Inyectar el servicio por const
constructor.
Crear la variable para las credenciales.
Crear la variable para los Claims.
Generar la firma, Signature.
2. Probar el token utilizando la URL respectiva en el cliente:
…/api/{ActionResult}

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Parte IV: Servicio de creación y autenticación de usuarios.

Este servicio lo desarrollaremos en la siguiente lección con los vídeos


¡Aplica ya!

¡El Aprendizaje Hecho Fácil!

VÍDEO N° 17

17. APIs CON C.A. – JWT I


¡El Aprendizaje Hecho Fácil!

VÍDEO N° 18

18. APIs CON C.A. – JWT II

¡El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Laboratorio I ¡Aplica Ya!


PARTE I, II

Después de esta lección aprenderá a…

Laboratorio I:

● Crear nuevas entidades en el almacén de datos subyacente (SQL Server).


● Configurar la nueva entidad en el proyecto.

● Implementar el servicio de autenticación para acceder a los servicios API

Laboratorio II:

● Implementar la creación de usuarios a través de la API.


● Crear la autorización para que un usuario pueda crear nuevos usuarios.

● Implementar encriptación de un password.

● Implementar la validación de credenciales y desencriptación.

¡El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Flujo de datos con Swagger


Hasta este punto de cierre al tema de seguridad y trabajo con Swagger, encontramos como
conclusión que el flujo de trabajo con esta herramienta podemos ilustrarlo así:

Como parte de la generación de las librerías cliente, se incluye la lógica de autenticación para
poder interactuar con las API. Swagger provee una serie de plantillas y archivos para simplificar
la integración con el consumo final de la API. Recuerde que toda API necesita autenticación para
que un usuario-cliente pueda realizar llamadas a la API, sea por su interfaz o haciendo uso de
Azure Active Directory (AAD), y a través del respectivo endpoint post/Login, proceso que se
realiza con los tokens de acceso, para nuestro caso, al portador (Bearer acceso token), esquema
de seguridad OpenApi que es un portador de seguridad ligero para otorgar acceso al cliente a
los servicios protegidos API.

A continuación se relaciona el diagrama UML para el resto de los laboratorios y siguiente


lección, relacionados con el proceso de autenticación, autorización, token y creación de un
usuario.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

UML: Diagrama de secuencia

¡El Aprendizaje Hecho Fácil!

En el diagrama se observa el proceso de autenticación y autorización cuando un usuario


solicita persomisos para la creación de nuevos estudiantes. Observe que una vez validadas las
credenciales, se verifica la regla de negocio
negocio,, que indica que solo los usuarios con rol de
administrador podrán crear nuevos estudiantes.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

UML: Diagrama de secuencia

¡El Aprendizaje Hecho Fácil!

Una vez verificada la validez de las credenciales del usuario y la regla de negocio, se procede a
generar el token que para efectos de nuestro laboratorio, se entrega en la misma UI Swagger,
así el usuario procederá a autenticarse en el sistema API con dicho token. De esta manera se la
habilita el endpoint respectivo PostAsync, HttpPost para la creación de un nuevo estudiante,
como lo verá en los siguientes laboratorios.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

CHECK LIST, Paso


so a paso

En los vídeos ¡Aplica ya! de esta lección desarrollaremos los siguientes pasos:

Parte I: Creando la entidad ‘usuario’


1. Crear la nueva tabla ‘
‘tblUsuario‘.
Capa: Base de datos.
2. Crear la entidad tblUsuario:
Capa: Core, Entidades
Entidades.
3. Configurar la nueva entidad:
Capa: Infraestructura, DAL, cursosContext.cs.
Agregar el nuevo DbSet.
4. Crear la configuración de la nueva entidad:
Capa: Infraestructura, DAL, Configuraciones.
Agregamos una nueva clases > UsuarioConfig
Tip: Copiar uno de los códigos de configuración para avanzar y ajustar
acorde a la tabla creada.
5. Instanciar la nueva configuración:
Capa: Infraestructura, DAL, DbContext.
- Refactorizar las instancias > ApplyConfiguration por >
ApplyConfigurationsFromAssembly
ApplyConfigurationsFromAssembly. Esto es registrar las configuraciones
configu
45
en el ensamblado.
- Actualizar los using.
6. Generar la Interfaz para la abstracción del Repositorio.
Capa: Core > Interfaces > IUsuarioRepo
7. Crear el respectivo Repositorio.
Capa: Infraestructura, Repositorios > UsuarioRepo

Parte II: Servicio de au


autenticación
8. Establecemos el nuevo servicio para la capa BLL de la entidad, es decir
la implementación de la anterior interfaz.

45
Todos los ensamblados .NET contienen la definición de tipos, la información de control de versiones para
el tipo, los metadatos y el manifiesto

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Este servicio debe inicialmente:


1. Verificar al usuario (por sus credenciales)
2. Validar su Perfil (Rol).
- Obtener las credenciales (login): hacemos uso del método Get del
repositorio. Si es válido entonces aplicar la Regla:
- Implementar la regla de negocio #2, solo usuario administrador!
(PerfilUsuario=1)
Capa: Core, Servicios > UsuarioBLL > GetPerfil( )
… ahora continuamos en la capa más externa > API > ControllerAPI

9. Diseñar el algoritmo para validar las credenciales del login-usuario:


Capa: Presentación > KeyApiController > ActionResult.
- Inyectar DI del servicio por constructor > UsuarioBLL
- Creamos el método asincrónico con una tupla que retornará dos valores
o items: (bool,<T>) para validar al usuario.El retorno devolverá dos
valores: si el usuario existe y el objeto complejo TblUsuario
- Ajustar el método > ValidarAutenticación, validando la dupla de
valores retornados.
- Ajustar la función > TokenGenerado, para recibir el objeto complejo
- Ajustar los datos quemados en los claims, para obtenerlos de la base
de datos.
NOTA: Nunca agregue la contraseña en el claim!

10. Realizar pruebas.(siguientes vídeos…)

Parte III: Servicio para la creación de nuevos usuarios y gestión desde la


API. En el siguiente paso a paso.

¡El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

PARTE III

Como se observó en el anterior laboratorio, hemos implementado las validaciones de


credenciales y puesta a punto para la autorización del proceso de creación de un nuevo
estudiante. Se describe ahora el proceso que facilita el token para finalmente habilitar el recurso
para creación de usuarios nuevos.

CHECK LIST, Paso a paso

Paso I: Creación de usuarios.

1. Realizar algo de refactorización y ajustes de código.


2. Crear el método para inserción de nuevos usuarios en el repositorio creado
en lecciones anteriores para la entidad Usuario :
Capa: Infraestructura, Repositorio.
3. Agregar el método anterior a la interfaz equivalente de servicios —
IUsuarioBLL creada en lecciones anteriores. Esto debido a la
implementación para futuras reglas de negocio:
Capa: Core, Interfaces, Interfaz<entidad, repositorio>.
4. Crear el DTO para la entidad Usuario:
Capa: Core, DTO.
5. Agregar el código para el mapeo de la entidad Usuario.
Capa: Infraestructura, mapeo.
6. Crear el controlador API para la creación de usuarios —Post(id)
Post(id)
Capa: Presentación, Controller.
7. Implementar el código para DI en el controlador, creand
creando
o los miembros
privados y el constructor para acceso al repositorio y el mapeo (IMapper)
por abstracción —Interfaces:
Interfaces:
Capa: Presentación, Controlador.
8. Diseñar nuestro método de tipo Task para inserción Post, [HttpPost] y
referenciar en los parámetros el DDTO
TO de la entidad respectiva:
Capa: Presentación, ActionResult.
9. Verificar y registrar servicios:
Capa: Presentación, Programa.cs
10. Habilitar la propiedad [Authorize] en el controlador y el servicio que
generará el Token,
, como veremos en la siguiente lección…
¡El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Compruebe sus conocimientos

Llene los espacios con el concepto correcto. Pueden sobrar términos o frases:

Frases: Payload, Autorización, Audience, Tokens, Claims, Autenticación, Issuer .

1. Los son artefactos informáticos de seguridad digital de


dos factores.
2. Cuando implementamos código para verificar las credenciales de un usuario

estamos creando el proceso de

3. corresponde a la carga útil de información básica de un


usuario.
4. Estas forman parte de un Token y comprenden todo el conjunto de

notificaciones reservadas

5. El o emisor identifica el emisor o servidor autorizado.


6. La identificación del destinatario previsto se define en la

Tome un screen y envíe sus respuestas a vuelta de correo para retroalimentación

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Después de esta lección aprenderá a…

Parte IV:

● Identificar los principales esquemas de seguridad OpenApi.


● Configurar la aplicación para el esquema HTTP Portador (Bearer).
● Utilizar el Token generado para habilitar la autorización a los servicios API.

¡El Aprendizaje Hecho Fácil!

46
Esquemas de seguridad OpenApi
Como aprendimos en lecciones anteriores, autenticación es el proceso para identificar que el
usuario que dice ser lo es realmente, haciendo uso de sus credenciales. Y la autorización alude a
los permisos que la aplicación otorga con base en las reglas del negocio para acceder a
recursos.

El estándar OpenApi hace uso de esquemas de autenticación y autorización HTTP que implica
utilizar la palabra reservada Authorization en el encabezado, y que se clasifican en:
1. Básico
2. Portador (Bearer)
3. Esquemas varios definidos por RFC 7235
4. Cookies
5. Oauth 2
6. OpenID Connect

Podráá profundizar de cada uno en el sitio a pie de página.

Haremos uso para el siguiente laboratorio de autenticación el esquema Bearer,, que es un


esquema simple como parte del protocolo HTTP.

46
Swagger.io

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

El encabezado enviado al servidor durante el request¸ llevará la palabra Bearer más la cadena
codificada en base64, y haciendo uso de protocolos de seguridad como HTTPS / SSL, y se verá
algo así:
Authorization: Basic ñsfkjgpadg*ñof==

47
Su descripción podrá ser algo similar a este código:
openapi: 3.0.0
...
components:
securitySchemes:
basicAuth: # <-- arbitrary name for the security scheme
type: http
scheme: basic
security:
- basicAuth: [] # <-- use the same name here

Configuración para el esquema Bearer (portador)


Para activar la seguridad relacionada con la autorización al hacer uso de Swagger, debemos
codificar dos métodos adicionales de acción en el contenedor de servicios de la aplicación y
como parte del servicio builder.Services.AddSwaggerGen(opt =>…
Estos son:

1. opt.AddSecurityDefinition
2. opt.AddSecurityRequirement

El primer método define los esquemas de seguridad para la protección API. Aquí podrá aplicar
cualquiera de los esquemas mencionados anteriormente, como se observa en el siguiente
código general:

El segundo método nos ayuda a controlar el esquema de autenticación aplicandolo a nivel


global o de operación. Por ejemplo, a nivel global cubrirá todos los endpoints. O nivel de

47
Ibid.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

operación para autorizar controladores o ActionResults de modo específico, como se observa en


este código:

PARTE IV

Como parte final del proceso de gestión de usuarios, credenciales y autorización para acceso a
recursos restringidos, realicemos el laboratorio que nos debe generar los siguientes resultados:

Podrá modificar el nombre del Controlador UsuarioController que hemos venido utilizando, por
LoginController o como lo prefiera, para brindar información al usuario.

Habilitar los servicios de autenticación Swagger


En la imagen se observa ya la implementación de los servicios de autenticación, gracias al uso
de los dos métodos descritos anteriormente, a saber: opt.AddSecurityDefinition y
opt.AddSecurityRequirement

Como puede notar, se ha habilitado el botón Authorize además de los íconos (candados) al final
de cada endpoint indicando al usuario que la API goza de un sistema de seguridad. El proceso a
seguir y que desarrollaremos en el siguiente laboratorio ¡Aplica ya! se resume así:

El usuario-cliente deberá solicitar un token desde el endpoint desplegado como se ve en la


imagen:

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Recuerde que el recurso para crear usuarios sólo está autorizado a usuarios con rol de
adminstradores (código 1). Ahora la API valida las credenciales y generará el token con un
tiempo de vida fijado acorde al contrato API, como se observa en la imagen:

El usuario en este punto ya ha sido autenticado. Es momento de solicitar su autorización para


acceder al servicio asociado al Post que le permita crear nuevos usuarios y desplegado en la
siguiente imagen:

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Recuerde que podrá asignar un


nombre distinto al endpoint
modificándolo de usuario por Login.
Esto es, cambiar el nombre del
ActionResult en la capa >
Presentación API > Controller.

Una vez obtenido el token, el usuario


autenticado debe hacer uso del
mecanismo o esquema de seguridad
Bearer para habilitar su autorización y acceso al servicio, copiando y pegando el token en la caja
de diálogo, como se observa en la imagen:

Finalmente, Swagger confirma la autorización una vez validado el Token.

Por su parte, el sistema API asegura el recurso modificando el estado abierto representado en el
icono del candado a cerrado.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

CHECK LIST, Paso a paso

Paso IV: Autorizando usuarios con un Token Bearer.

1. Crear el método AddSecurityDefinition como se observa en la imagen:

2. Implementar el método AddSecurityRequirement:

3. Realizar las pruebas. Las explicaciones del código se realizan en los vídeos de la lección.

¡El Aprendizaje Hecho Fácil!

VÍDEO N° 19 – 23

19. APIs CON C.A. - Usuarios I


20. APIs CON C.A. - Usuarios II
21. APIs CON C.A. - Usuarios III
22. APIs CON C.A. - Usuarios IV
23. APIs CON C.A. - Usuarios V

¡El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Después de esta lección aprenderá a…

● Incluir en su programación el principio Don’t Repeat Yourself (DRY).


● Reconocer los tipos de patrones para repositorios.
● Implementar un repositorio genérico UnitOfWork con Clean Architecture.

¡El Aprendizaje Hecho Fácil!

Repositorio y UnitOfWork

El repositorio y la unidad de patrones de trabajo


trabajo(UoW) están destinados a crear una capa de abstracción entre la
capa de acceso a datos y la capa de lógica empresarial de una aplicación.

La implementación de estos patrones puede ayudar a aislar la aplicación de los cambios en el almacén de
datos y puede facilitar las pruebas unitarias automatizadas o el desarrollo basado en pruebas (TDD). 48

¡El Aprendizaje Hecho Fácil!

El principio DRY
Don’t Repeat Yourself

O DIE —Duplicidad está mal. Este acrónimo es un principio aplicado al desarrollo de software
que facilita la reducción de comportamientos o patrones de código repetitivo, evitando la
redundancia. En el libro The Pragmatic programmer49 (El El programador pragmático)
pragmático se indica que
al aplicar este principio y realizar posteriores modificaciones, no se requerirán cambios o al
menos significativos en el resto de los elementos. Es decir, se busca reutilizar código existente.

La duplicidad de código influye en la facilidad de mantener el ssoftware,


oftware, corregir bugs y aplicar
cambios o mejoras, evitando el famoso código espagueti, además de su impacto en la
productividad y calidad final. Hacer uso de las Buenas prácticas en la industria del software es el
mejor propósito.

48
Microsoft, Tom Dykstra.
49
Andy Hunt, Dave Thomas.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Cuando revisamos la estructura


tructura general de una aplicación tipo API, encontramos que su
comportamiento básico se centra en el CRUD y de manera reiterativa en todos los endpoints.

Como ha estudiado hasta aquí, las entidades del modelo requieren además de estas
operaciones de mantenimiento
tenimiento de datos, al igual que el protocolo HTTP, sus verbos y los
Queries (SQL) implicados en el proceso. Son estructuras algorítmicas predecibles. Todo esto nos
señala la importancia de comprender desde el principio los requerimientos de usuario para
definir los módulos comunes a toda la aplicación, como las funciones vistas en la lección
anterior —autenticación
autenticación y autorización API. Abstraer este tipo de necesidades del usuario
permitirá minimizar la redundancia de código y centralizar la funcionalidad de modo genérico y
globalizado.

Repositorios
Patrón

El patrón Repositorio según Martin Fowler

“… Un repositorio realiza las tareas de intermediario entre las capas del modelo de dominio y la asignación de
datos, actuando de manera similar a un conjunto de objetos de dominio en la memoria. Los objetos del cliente
crean consultas mediante declaración y las envían a los repositorios para obtener respuestas.

Conceptualmente, un repositorio encapsula un conjunto de objetos almacenados en la base de datos y las


operaciones que se pueden realizar con ellos, proporcionando una forma que está más cerca de la capa de
persistencia.

Los repositorios, también, apoyan el propósito de separar, claramente y en una dirección, la dependencia entre el
50
dominio de trabajo y la asignación de datos“

¡El Aprendizaje Hecho Fácil!

Como puede observar, este patrón está orientado a abstraer la relación entre las capas de
acceso a datos (dominio y entidades) con su lógica, y la capa de la lógica empresarial. Ya ha
visto en laboratorio anteriores las clases dedicadas a los repositorios y que constituyen una
parte importante de la capa Infraestructura en proyectos que hacen uso de la arquitectura Clean
Architecture.

50
Patterns of Enterprise Application

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Inconvenientes a resolver con un repositorio


Como parte de los grandes inconvenientes de acceder de modo directo desde el Core de la
aplicación a la fuente de datos, asunto que se resuelve con la aplicación de patrones o
arquitecturas tipo Onion como la estudiada hasta aquí (Clean Architecture), tenemos:

● Código duplicado
● Un mayor potencial de errores de programación
● Escritura débil de los datos profesionales
● Dificultad para centralizar las directivas relacionadas con los datos, como el
almacenamiento en caché
● Incapacidad para probar fácilmente la lógica empresarial de forma aislada de las
dependencias externas
● Fuerte adhesión, acoplamiento y dependencias.

Ventajas de un repositorio
Como parte de las ventajas de hacer uso de este patrón encontramos:
1. Facilitar el Testing por el desacople de dependencias.
2. Mantenimiento y legibilidad de código.
3. Eliminar la redundancia gracias al reuso de la lógica de conexión a datos desde cualquier
usuario y para el resto de los objetos que realizan requests.
4. Establecer un solo canal para realizar mantenimiento de datos en la fuente de datos. El
área transaccional51 (actualizaciones), siempre será gestionada por los repositorios.

Tipos de repositorios
Como parte de la clasificación de repositorios encontramos:

Repositorios por entidades


Este diseño de repositorios se basa en la
creación de una clase especializada de
repositorio dedicada a cada una de las
entidades del modelo, fuertemente
tipadas.

Ejemplo:
En laboratorios anteriores hemos
implementado este tipo de repositorios
para las entidades Estudiante y Usuario

51
Una transacción es una forma de agrupar, o juntar por lotes, una serie de actualizaciones de un origen
de datos para que todas se confirmen a la vez o no se confirme ninguna si se deshace la transacción. Si no
usa una transacción, los cambios realizados en el origen de datos se confirman automáticamente en lugar de
confirmarse a petición. Microsoft.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

como se observa en la imagen anterior, EstudianteRepo y UsuarioRepo

Repositorio genérico
Este tipo de repositorios facilita centralizar todas las operaciones CRUD en un solo repositorio
que será utilizado por la entidades del modelo. Entremos a revisar este tipo de patrón de
ddiseño a continuación.

Patrón Unit of Work (UoW)


La unidad clase de trabajo tiene un propósito: asegurarse que cuando utilice varios repositorios,
compartan un único contexto (DBContext) de base de datos.

De esa manera, cuando una UoW está completa, puede llamar al método transaccional en esa
instancia del contexto y estar seguro de que todos los cambios relacionados se coordinarán.
Todo lo que la clase necesita es un método especializado en la transacción y una propiedad
para cada repositorio.52

En resumen: todas las transacciones (CRUD) en una unidad UoW se realizan en una sola
transacción haciendo uso de una única instancia del DbContext como se observa en la
siguiente imagen.

52
Microsoft

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

En términos generales, al incluir el enfoque co


con el patrón Unit of Work (UoW) agregamos una
capa de abstracción en nuestro diseño. Observe el proceso relacionado entre el repositorio,
persistencia y lógica empresarial con UoW. Recuerde que el desacoplamiento lo hemos logrado
gracias a las interfaces que
e sirven de mecanismos entre las peticiones del cliente (servicios) y la
capa de datos como usted ha practicado en laboratorios hasta este punto.

Los repositorios y la Unit of Work garantizan que todos utilicen el mismo DbContext.

Data Mapper

Un repositorio emite las consultas adecuadas al origen de datos y, a continuación, asigna los conjuntos de
resultados a las entidades empresariales expuestas externamente. Los repositorios a menudo usan el patrón Data
53
Mapper para traducir entre representaciones. Los repositorios eliminan las dependencias que los clientes que
llaman tienen en tecnologías específicas.

AutoMapper AutoMapper es un asignador objeto


objeto-objeto. La asignación objeto-objeto
objeto funciona transformando un
objeto de entrada de un tipo en un objeto de salida de un tipo diferente. Las preocupaciones de una capa a
menudo entran en conflicto con las preocupaciones de otra, por lo que la asignación objeto
objeto-objeto
objeto conduce a
modelos
odelos segregados, donde las preocupaciones de cada capa pueden afectar solo a los tipos de esa capa.

¡El Aprendizaje Hecho Fácil!

Laboratorio ¡Aplica ya!


PARTE I

CHECK LIST, Paso a paso

Aplicando el patrón Repositorio Genérico

1. Entidad base: Crear la clase especializada en el control de nuestro repositorio tipo UOW.
Capa -> Core, Entities, EntidadBase.
- Declarar la propiedad tipo Id universal como llave primaria (PK)
2. Cada Entidad hereda de la clase base…
- Capa ->> Core, Entities, cada una he
hereda de EntidadBase
- Eliminar las propiedades ID (PK) en cada Entidad del modelo

o reemplazarlas por el ID maestro.

53
https://docs.automapper.org/en/latest/Getting
https://docs.automapper.org/en/latest/Getting-started.html

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

3. Renombrar por la propiedad maestra ID, las PK de cada entidad relacionada en Configuración
Capa - > Infraestructura ->
> DAL -> Configuraciones

4. Repositorio Genérico: Registrar los repositorios genéricos para cada entidad:


- Crear la Interfaz para el repositorio genérico
Capa: Core -> > Interfaces, IRepoGenerico
- Referenciar la entidad base como tipo -> < T >
5. Registro de los métodos genéricos relacionados con las operaciones CRUD genéricas
Capa -> Core -> > Interfaces
6. Implementación de la interfaz del repositorio genérico
Capa -> Infraestructura -> > Repositorios -> RepoGenerico
7. Aplicamos DI para para la conexión a la fuente de datos y el DbContext
Capa -> Infraestructura -> > Repositorios -> RepoGenerico
- Registramos un DbSet de tipo genérico y aplicamos DI para establecer (Set) la entidad respectiva de
tipo < T >
- Implementación de los métodos CRUD genéricos

8. Registro del servicio (interfaz) en el contenedor de servicios


Capa ->> Presentación API -> Program
builder.Services.AddScoped(typeof(IRepoGenerico<>), typeof(RepoGenerico<>));
- Eliminar los servicios de repositorios iniciales.

9. Aplicar herencia a cada entidad del modelo de la nueva EntidadBas


EntidadBase
Capa -> Core ->> Entidades

10. Reemplazar las interfaces referenciadas en cada servicio, por la interfaz del nuevo repositorio genérico -
> IRepoGenerico
Capa -> Core ->> Servicios
-Ajustar
Ajustar los métodos actuales por los genéricos.

¡El Aprendizaje Hecho Fácil!


Fáci

VÍDEO N° 24

24. APIs CON C.A. - Repositorio Genérico I

¡El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Laboratorio ¡Aplica ya!


PARTE II

Recuerde que…

Con Unit of Work todos los repositorios se hallan incluídos o agrupados.

Así, dependiendo del Core de negocio, se tendrán UoW para cada unidad de trabajo por el modelo de negocio
para ventas, compras, etc.

Además se podrá compartir una sola instancia de conexión a la base de datos para todos los repositorios.
reposi

¡El Aprendizaje Hecho Fácil!

CHECK LIST, Paso a paso

Aplicando el patrón UoW : Entidad Estudiante

1. Interfaz UoW: Creación


2. Aplicar herencia a cada entidad del modelo de la nueva EntidadBase
Capa -> Core ->> Interfaces -> IUoW
- Que implemente Idisposable

3. Registro el repositorio genérico para cada entidad como propiedades


Capa -> Core -> > Interfaces
-Registrar
Registrar los métodos necesarios genéricos para registro de cambios.

4. Implementar IUoW
Capa - > Infraestructura ->
> Repositorios, UoW

5. DI para manejo de la cadena de conexión a través del DbContext.

6. Encapsular para instanciar con el repositorio genérico IRepoGenerico cada entidad del modelo existente.

7. Ajustar los miembros o firmas implementadas de la interfaz que corresponden a cada entidad y su
repositorio genérico.

¡RECUERDE!:
Con UoW se hace uso de la MISMA INSTANCIA DEL CONTEXTO para cada repositorio genérico!

- Validamos el retorno de cada método


método-repositorio
repositorio genérico, haciendo uso del mismo contexto.

¡Tenga presente!: Con UoW el CRUD es genérico!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

- Implementamos las firmas relacionadas con guardar o registrar cambios.

8. Implementar el Dispose para liberar el Context

9. Registrar el servicio para la nueva interfaz - > IUoW

Finalmente…

10. Referenciar nuestro UoW en cada servicio para acceder a su repositorio genérico respectivo.
- DI para inyectar el UoW.
Capa Core -> Servicios

¡El Aprendizaje Hecho Fácil!

VÍDEO N° 25

25. APIs CON C.A. - Repositorio Genérico UoW - II


¡El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Compruebe sus conocimientos

Marque las respuesta correctas:

Los repositorios son patrones de diseño para crear capas de abstracción


entre los datos y la lógica de negocio

Aplicar el principio DRY nos ayuda a evitar la redundancia, identificar


estructuras de código predecibles y reuso de código

El área transaccional (actualizaciones), siempre será gestionada por los


repositorios.

El repositorio genérico se focaliza en crear clases especializadas por


p
cada entidad del modelo

Para centralizar las operaciones CRUD se implementa un repositorio de


clases.

UoW facilita agrupar todos los repositorios tipo clases y varios


contextos

Todo lo que la clase necesita es un método especializado en la


transacción y una propiedad para cada repositorio, algo fundamental en el
patrón UoW.

Todas
odas las transacciones (CRUD) en la UoW se realizan en una sola
transacción haciendo uso de una única instancia del DbContext

AutoMapper AutoMapper es un asignador o


objeto-objeto.
objeto. La asignación
objeto-objeto
objeto funciona transformando un objeto de entrada de un tipo en un
objeto de salida de un tipo diferente.

Todas
odas las transacciones (CRUD) en la UoW se realizan en una sola
transacción haciendo uso de una única instancia del DbContext

Es fundamenta en el patrón UoW, implementar el método Dispose para


libera el Context

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Después de esta lección aprenderá a…

1. Identificar qué es Azure y las alternativas para sus aplicaciones.


2. Identificar el servicio para despliegue de la aplicación en la nube.
3. Implementar alternativas de despliegue para su API en la nube a través de los laboratorios ¡Aplica
ya! de esta lección.

¡El Aprendizaje Hecho Fácil!

Azure
Esta plataforma de nube pública y privada de Microsoft, ofrece informática en la nube
entregando servicios con un amplio catálogo de soluciones como almacenamiento, software,
utilidades, análisis, servidores, detección de amenazas, bases de datos entre otras. Facilita
F una
innovación rápida y economía de escala, reduciendo costos operativos. Se cobra por lo que se
utiliza.

Fuente: Microsoft

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Azure ofrece más de cien servicios para la ejecución de aplicaciones de desarrolladores de IT


facilitando procesos de compilación, implementación y administración de aplicaciones como lo
haremos con nuestra API. Con Azure va más allá con los servicios de inteligencia artificial y
aprendizaje automatizado. Todo contenido en el concepto de virtualización que permite la
separación y desacoplamiento entre el hardware y un sistema operativo, gracias a la
abstracción y emulación de máquinas virtuales las cuales podrán ejecutar servicios en
cualquier sistema operativo.

Azure Devops

DevOps reúne a individuos, procesos y tecnología mediante la automatización de la entrega de software para
ofrecer un valor continuo a los usuarios.

Con Azure DevOps puede crear, compilar y publicar canalizaciones que proporcionan integración, entrega e
implementación continuas de las aplicaciones.

Puede integrar los repositorios y las pruebas de aplicaciones, realizar la supervisión de aplicaciones y trabajar
con artefactoss de compilación. También puede trabajar con elementos de trabajo pendiente para realizar el
seguimiento, automatizar la implementación de la infraestructura e integrar una gama de herramientas y
servicios de terceros.

Todas estas funciones y muchas más eestán


stán estrechamente integradas con Azure para permitir
implementaciones coherentes y reproducibles para que las aplicaciones proporcionen unos procesos de
54
compilación y lanzamiento optimizados.

¡El Aprendizaje Hecho Fácil!

Cuenta gratuíta Azure

Si no está familiarizado con Azure, puede registrarse para obtener una cuenta gratuita en el sitio web de Azure y,
de este modo, empezar a explorar sin costo alguno.

¡El Aprendizaje Hecho Fácil!

54
Microsoft

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

En la siguiente ilustración se resume una cuenta de Azure. Para crear y usar los servicios de
Azure, necesita una suscripción de Azure. Después de crear una cuenta de Azure, puede crear
suscripciones adicionales. Por ejemplo, es posible que la empresa use una única cuenta de Azure
para el negocio, y suscripciones independientes para los departamentos de desarrollo,
marketing y ventas.

Fuente: Microsoft

La cuenta gratuíta será suficiente para realizar la migración de nuestra API, lo que nos
proporciona acceso a productos populares por un año y acceso a más de 40 productos que
siempre son gratuítos, de modo similar que una cuenta de estudiante.

Una de las grandes fortalezas


de esta plataforma es la
seguridad. Azure tiene más
certificaciones que cualquier
otro proveedor de servicios en
la nube. En la imagen se
observan algunas de estas que
podrá ampliar en el link a pie
de página: 55

55
https://azure.microsoft.com/es-mx/explore/security/

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Escenarios de desarrollo
Para incorporar Azure con sus aplicaciones, debe considerar las necesidades durante la
programación de código,, desarrollo y las expectati
expectativas
vas de los clientes. Tenemos en resumen los
siguientes escenarios:
1. Sin servidor: Esto es, experiencia de desarrollo completa! Utilice los servicios de Azure
Functions que ofrece más de 250 conectores a otros servicios y en general, todos los
relacionados conon un servidor en la nube. Permite programar, compilar y depurar
localmente sin configuraciones extras. Además tiene integración automática con
DevOps.
Esta alternativa ofrece programar en los lenguajes de programación más populares y
variados escenarios como la implementación de aplicaciones web, APIs con .NET, Node.js
o Java; flujos de trabajo de aprendizaje automático con Python y automatización en la
nube con PowerShell. 56
2. En la nube desde aplicaciones
aplicaciones:: No se requiere modificar la arquitectura de nuestras
nues
aplicaciones o modelo de implementación actual. Puede tener su aplicación localmente e
integrar servicios Azure para ampliar la funcionalidad.

Azure Key Vault

Por ejemplo, el servicio de Azure Key Vault sería un gran valor agregado para nuestra API pues permite almacenar
de forma segura y controlar de modo estricto el acceso a tokens, contraseñas, administración de certificados de la
capa de transporte y sockets seguros (TLS/SSL) públicos y privados, administración y control de claves de API, y
otros secretos.

Lo anterior significa que ya no tendrá que almacenar localmente o en la aplicación datos secretos como la famosa
cadena de conexión que hemos implementado en laboratorios anteriores.

¡El Aprendizaje Hecho Fácil!

3. Hospedaje en Azure:: Podrá hospedar toda la pila de la API, aplicaciones web hasta
nuestra base de datos y servicios de almacenamiento.

56
Microsoft

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Azure App Service


Servicio PaaS – Plataforma como Servicio

Este servicio provee hospedaje escalable para aplicaciones web, API REST y servicios de back-
end. App Service admite código escrito en .NET Core, .NET Framework, Java, Ruby, Node.js, PHP
y Python. App Service es recomendable para la mayoría de los sitios web, especialmente si no se
necesita un control estricto sobre la infraestructura de hospedaje.

Azure App Service es un servicio basado en HTTP, que facilita el hospedaje de aplicaciones web,
API de REST por ejemplo. También puede aprovechar sus capacidades de DevOps, como la
implementación continua desde Azure DevOps, GitHub, Docker Hub y otros orígenes, la
administración de paquetes, los entornos de ensayo, el dominio personalizado y los certificados
TLS/SSL.

Acceso a Azure desde .Net


Tanto si la aplicación está hospedada en Azure como localmente, el acceso a la mayoría de los
servicios de Azure se proporciona a través del SDK de Azure para .NET. El SDK de Azure para
.NET corresponde a una serie de paquetes NuGet, como se observa en la ilustración:

Fuente: Microsoft

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Alternativa para publicación de una aplicación


Para desplegar la API diseñada a este punto usaremos dos alternativas:

1. Modelo On Premises: La aplicación se despliega en un servidor local, empresarial, un


datacenter propio o un servidor dedicado, todo con personal de la organización para su
administración.
También es posible esta alternativa creando una máquina virtual en la nube.
2. Cloud, PaaS: o Plataforma como servicio.

On premises deployment con .Net Core


Centro de datos en el cliente

On premises es el despliegue e implementación de nuestras aplicaciones de modo local o en las


instalaciones propias o del cliente. Esto facilita el control sobre la seguridad, datos,
configuraciones personalizadas y datos fuera de línea. Es decir, el control es completo pero tiene
sus costos y complejidad.

Para el laboratorio de la lección implica que el servidor de la aplicación IIS y la base de datos
de Microsoft SQL Server se ejecutarán en nuestra máquina o cliente. Puede implementar una
aplicación de .NET Core como:
1. Una implementación dependiente del marco, que incluye los binarios de la aplicación
pero depende de la presencia de .NET Core en el sistema de destino. Los usuarios de la
aplicación tienen que instalar por separado el tiempo de ejecución de .NET.
2. Como una implementación autónoma, que incluye los binarios de la aplicación y de .NET
Core. Es decir, los usuarios de la aplicación pueden ejecutarla en un equipo que no tenga
instalado el tiempo de ejecución de .NET.

Ambos modos de publicación producen un ejecutable específico de la plataforma de forma


predeterminada. Las aplicaciones dependientes del marco se pueden crear sin un ejecutable y
estas aplicaciones son multiplataforma. 57

Los archivos binarios multiplataforma se crean cuando publicas la aplicación


como dependiente del marco, en forma de archivo dll.

El archivo dll lleva el nombre del proyecto. Por ejemplo, para nuestra API ‘Escuela Norte’, se crea
un archivo denominado escuela_norte.dll. Las aplicaciones publicadas de esta manera se
ejecutan con el comando .dotnet <filename.dll> y se pueden ejecutar en cualquier plataforma

57
Microsoft

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Un ejecutable no es multiplataforma

Los ejecutables no son multiplataforma.

Son específicos de un sistema operativo y una arquitectura de CPU. Al publicar la aplicación y crear un ejecutable,
puede publicarla como autónoma o dependiente del marco.

La publicación de una aplicación como autónoma incluye el tiempo de ejecución de .NE.NETT con la aplicación, y los
usuarios de la aplicación no tienen que preocuparse por instalar .NET antes de ejecutar la aplicación.

Las aplicaciones publicadas como dependientes del marco no incluyen el tiempo de ejecución y las bibliotecas de
58
.NET; solo see incluyen la aplicación y las dependencias de terceras partes .

¡El Aprendizaje Hecho Fácil!

Laboratorio ¡Aplica ya!


Parte I: On Premises deployment

Implementar y publica una App

Publicar una aplicación significa generar una aplicación compilada que se puede hospedar en un servidor.

Implementar una aplicación significa trasladar la aplicación publicada a un sistema de hospedaje.

El paso de publicación lo controla el SDK de .NET Core, mientras que el paso de implementación se puede
controlar
trolar mediante distintos enfoques.

En este tutorial se adoptan dos enfoques de implementación:


1. De carpetas, donde:
● La aplicación se publica en una carpeta.
● El contenido de la carpeta se mueve a la carpeta del sitio de IIS (la ruta de acceso física al sitio
en el Administrador de IIS).
2. Cloud, Azure: La aplicación se publica en una suscripción previa en la nube tipo servicio SaaS. Podrá
hacer uso de las principales plataformas. Para nuestro laboratorio utilizaremos Azure Devops.

¡El Aprendizaje Hecho Fácil!

58
Ibdi

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Verificaciones iniciales
El paso a paso nos guiará en el proceso de publicación de la API. Adoptando el enfoque de
carpetas.. Para poder correr nuestra API en el servidor local, realizaremos las siguientes
verificaciones básicas:

CHECK LIST, Paso a paso

Parte I: Verificando herramientas y configuraciones previas

Verificaciones iniciales:

1. Verifique en características de Windows los paquetes necesarios como se observa en las


siguientes figuras:

Ruta: Panel de control > Programas y características > Activar o desactivar las
características de Windows

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

No olvide seleccionar esta opción.


Evitará el siguiente error que se
muestra en la imagen.
Nota: Se recomienda reiniciar su
sistema.

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

2. Verificar que su sistema operativo cuenta con IIS (Servidor de Microsoft Windows)
Ruta: Panel de control como se observa en la imagen:
Nota: Ideal si tiene la versión más actualizada.

3. Instale o comprube si está instalado Microsoft SQL Server Management Studio, en su panel
de control:

4. Para poder desplegar los servicios de .NET Core en IIS necesita el instalador .NET Core
Hosting Bundle el cual prepara IIS para .net core.
Verificar si se tiene instalado el Hosting Bundle como se ve en la figura:
Nota: para esto, ya debe tener instalado su administrador de IIS Services:
1. Abra el IIS Services y ubique y abra en el panel principal la opción > Módulos.
2. Verifique si el paquete de la figura se halla instalado:

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño. Series desde cero. https://vladodotnet.wordpress.com/

De lo contrario realice la instalación.


Nota: Si ya lo tuviese, se recomienda reinstalarlo nuevamente para limpiar configuraciones que
puedan arrojar errores.

5. Instalamos el Hosting Bundle para Windows. Utilice el link a pie de página.59

Finalizadas las instalaciones y preparación previa a la publicación On Premises, es decir, en el servidor


local de la organización, continúe su paso a paso.

Parte II: Instalado nuestra API en IIS local para despliegue

1. Ejecute Visual Studio como Administrador y verifique en la barra.


2. (Opcional) Agregue código al contenedor de servicios
Capa > Presentación > Program.cs
3. Publique su aplicación. En el servidor local IIS
Capa > Clic derecho > Publicar > Carpeta
4. Creando el sitio en IIS: Abra el administrador de IIS
a. Verifique el el servidor se encuentra corriendo
Clic derecho sobre nombre del servidor…
b. Su nuevo sitio: Clic derecho en > Sitios
Agregue y configure su sitio como se ve en el vídeo…
5. Despliegue del sitio API con IIS…
Posibles Bugs: Verifique la lista de errores en la siguiente tabla.

¡El Aprendizaje Hecho Fácil!

59
https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-aspnetcore-6.0.10-windows-hosting-
bundle-installer

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar-vallejo-vlado/


VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

VÍDEO N° 26

26. APIs CON C.A. - Deploy On Premises


¡El Aprendizaje Hecho Fácil!

Laboratorio ¡Aplica ya!


Parte II: OnCloud deployement

Finalice ahora subiendo su API a la nube de Azure.

CHECK LIST, Paso a paso

Preparando Azure

1. Deberá crear una cuenta Azure y loguearse


2. Crear un Resource groups > + Create >

Publicando el proyecto

1. Ajustar el [Route] en cada controlador API


2. Ejecutar > Publish
3. Crear un recurso > API Management

¡El Aprendizaje Hecho Fácil!

VÍDEO N° 27, 28

27. APIs CON C.A. - Deploy OnCloud I


28. APIs CON C.A. - Deploy OnCloud II

¡El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Siguiente paso nivel avanzado II

Implemente su Carrito de Compras

Diseño elegante y depliegue


depl de
información en fichas

¡Notifique al usuario!

 Seguridad JWT
 Proveedores externos
 ¡Pasarelas de pago!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Apéndice A
Relación de los vídeos aduntos al curso.

VÍDEOS: Practicando con SOLID


SOLID, C#

¡Aplica ya! Vídeo tutorial, paso a paso.

Vídeo 29 Caso #1: Principio SOLID SRP


Vídeo 30 Caso #2: Principio SOLID OCP
Vídeo 31 Caso #3: Principio SOLID LSP
Vídeo 32 Caso #3: Principio SOLID LSP variante
Vídeo 33 Caso #4: Principio SOLID ISP
Vídeo 34 Caso #5: Principio SOLID IoC

El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/
VladoDotNet – Ingeniería de software y Diseño
Diseño. Series desde cero. https://vladodotnet.wordpress.com/

Apéndice B

VÍDEO 35: Comportamiento de los ciclos de vida

¡Aplica ya! Vídeo tutorial, paso a paso.

Vídeo 35: Prácticando con los ciclos de vida.

El Aprendizaje Hecho Fácil!

Ingeniero Senior, MBA, DBA César Vallejo linkedin.com/in/cesar


linkedin.com/in/cesar-vallejo-vlado/

También podría gustarte