.NET

Contenedores y despliegue

  • Docker
    • Containerize an app with Docker tutorial - .NET-build-containertabs=windows&pivots=dotnet-9-0
    • Buenas prácticas al contenerizar apps .NET
      • Usa imágenes base oficiales de .NET (runtime y SDK separadas).
      • Implementa multi-stage builds para reducir el tamaño de la imagen.
      • Define variables de entorno para ASPNETCORE_ENVIRONMENT y logging.
      • Utiliza ENTRYPOINT y CMD correctamente para servicios y tareas programadas.
      • Gestiona secrets con herramientas como Docker secrets, Azure Key Vault o AWS Secrets Manager.
    • Integración con CI/CD
      • Usa GitHub Actions o Azure Pipelines para automatizar el build y push al registry.
      • Escanea vulnerabilidades en imágenes con herramientas como trivy o dockle.

Hojas de cálculo y automatización

  • visual basic VBA
  • [Aspose.Cells for .NET Documentation](https://docs.aspose.com/cells/net/)
  • ClosedXML - GitHub
  • app para exportar a excel con plantillas angular, net y cell 🔥

Librerías y frameworks destacados

  • Aspose.Cells for .NET
    • Permite crear, leer y modificar archivos Excel programáticamente.
    • Soporta fórmulas, gráficos, pivot tables y estilos complejos.
    • Ideal para automatización de reportes o generación de hojas de cálculo sin depender de Excel instalado.
  • ClosedXML
    • API fluida y sencilla sobre OpenXML.
    • Permite manejar .xlsx y .xlsm con enfoque declarativo.
    • Ejemplo básico:
	using ClosedXML.Excel;

	var workbook = new XLWorkbook();
	var worksheet = workbook.Worksheets.Add("Datos");
	worksheet.Cell(1, 1).Value = "Nombre";
	worksheet.Cell(1, 2).Value = "Edad";
	worksheet.Cell(2, 1).Value = "Eduardo";
	worksheet.Cell(2, 2).Value = 29;
	workbook.SaveAs("Reporte.xlsx");
	```

- **VBA (Visual Basic for Applications)**
	- Permite automatizar tareas dentro de Excel u Office.
	- Combinable con .NET a través de COM Interop o scripts externos.
	- Ejemplo: desde .NET, ejecutar macro VBA existente:
	
```csharp
	var excelApp = new Microsoft.Office.Interop.Excel.Application();
	var workbook = excelApp.Workbooks.Open("C:\\reportes\\macro.xlsm");
	excelApp.Run("ActualizarDatos");
	workbook.Close(true);
	excelApp.Quit();
	```


### Integración de .NET con Excel
- Exportar datos desde aplicaciones .NET (ej. ASP.NET, MAUI o WinForms) a plantillas Excel.
- Uso de librerías para reportes con estilos corporativos.
- Automatización de tareas repetitivas (generar reportes diarios, leer inventarios, procesar celdas).
- Integración con Angular o frontend SPA:
	- Backend .NET genera el archivo Excel.
	- Angular descarga el archivo con `FileSaver.js` o similar.
	- Ideal para sistemas administrativos o ERP modulares.

## Ampliaciones y temas relacionados
- Entity Framework Core para acceso a datos en entornos .NET.
- Blazor como alternativa web a Angular/React en ecosistema .NET.
- Testing en .NET (xUnit, NUnit, Moq).
- [CICD](/devops/cicd/) para pipelines automatizados.
- Microservicios con .NET usando gRPC o REST.
- Performance y profiling .NET con herramientas como dotTrace y BenchmarkDotNet.


---
# .NET  Ampliación de conceptos avanzados  

## Arquitectura y diseño avanzado
- **Patrones de arquitectura aplicados a .NET**
	- **Clean Architecture** y **Onion Architecture**: separan las capas de dominio, aplicación e infraestructura, facilitando el mantenimiento y los tests.
	- **Domain-Driven Design (DDD)**: organiza el código alrededor del dominio empresarial.  
		- Uso de **Value Objects**, **Entities**, **Aggregates**, **Repositories** y **Domain Events**.  
		- Compatible con **CQRS** y **Event Sourcing** para separación de lectura/escritura y auditoría histórica.
	- **Microservicios con .NET**:
		- Comunicación con [gRPC](/backend/grpc/) o mensajería (RabbitMQ, Azure Service Bus).
		- Uso de **API Gateway** (Ocelot, YARP) para enrutar peticiones.
		- Sincronización de datos eventual con eventos distribuidos.
	- **Modular Monoliths**: estructura intermedia entre monolito y microservicio; permite escalar de forma controlada.

- **Patrones de diseño comunes**
	- **Dependency Injection** (DI): estándar en .NET Core mediante `IServiceCollection`.
	- **Factory**, **Strategy**, **Observer**, **Decorator**, **Mediator**: patrones que se implementan fácilmente con C# gracias a delegates, interfaces y eventos.
	- **Command Pattern** para desacoplar acciones de UI en [MAUI NET](/desarrollo%20multiplataforma/maui-net/) o [xamarin](/desarrollo%20multiplataforma/xamarin/).

## Ecosistema moderno de desarrollo .NET
- **Rendimiento y runtime**
	- **.NET 9 y AOT (Ahead-of-Time Compilation)**: permite generar binarios nativos más rápidos y ligeros.
	- **Span\<T\> y Memory\<T\>**: optimización de acceso a memoria.
	- **Minimal APIs** en [ASP NET](/backend/asp-net/) para servicios ligeros.
	- **NativeAOT** para entornos sin runtime preinstalado.

- **Interoperabilidad multiplataforma**
	- [MAUI NET](/desarrollo%20multiplataforma/maui-net/) para apps móviles, escritorio y web híbrido.
	- Blazor y WebAssembly: ejecutar C# en el navegador sin JavaScript.
	- Integración con android mediante bindings nativos o APIs de plataforma.
	- Comunicación entre [cpp](/software%20engineering/cpp/) y .NET vía P/Invoke o C++/CLI.

- **Integración con contenedores y nube**
	- [Docker](/software%20engineering/docker/) como entorno de ejecución portátil.
	- Publicación directa en [Azure](/cloud/azure/) con `dotnet publish --os linux --arch x64 /t:PublishContainer`.
	- Uso de **Kubernetes** con configuraciones Helm o manifestos YAML.
	- Logs centralizados mediante **Serilog** o **Seq**.

## Herramientas de productividad y automatización
- **Builds y DevOps**
	- CI CD con GitHub Actions, Azure DevOps o Jenkins.
	- Versionado semántico automatizado con `GitVersion`.
	- Análisis estático con **SonarQube** o **Roslyn Analyzers**.

- **Testing**
	- Unit testing con **xUnit** o **NUnit**.
	- Mocking de dependencias con **Moq** o **NSubstitute**.
	- **Integration Tests** con `WebApplicationFactory` en ASP.NET Core.
	- **Benchmarking** con **BenchmarkDotNet**.

## Integración con hojas de cálculo y documentos
- [visual basic VBA](/software%20engineering/visual-basic-vba/) para automatización nativa.
- **ClosedXML**, **Aspose.Cells**, y **EPPlus** como principales librerías .NET para Excel.
- Generación de reportes corporativos:
	- Plantillas Excel dinámicas con placeholders.
	- Exportación a PDF combinando Aspose.Cells + Aspose.PDF.
	- Automatización de reportes financieros o logs operativos.

### Ejemplo: generación avanzada de reportes con ClosedXML

```csharp
using ClosedXML.Excel;
using System.Data;

public class ReportGenerator
{
	public void Generate(DataTable data)
	{
		using var workbook = new XLWorkbook();
		var ws = workbook.Worksheets.Add("Reporte");
		// Encabezados
		for (int i = 0; i < data.Columns.Count; i++)
			ws.Cell(1, i + 1).Value = data.Columns[i].ColumnName;

		// Cuerpo
		ws.Cell(2, 1).InsertData(data.AsEnumerable());
		// Estilo
		ws.RangeUsed().Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
		ws.Columns().AdjustToContents();
		workbook.SaveAs("ReporteAvanzado.xlsx");
	}
}

`

Extensiones y ecosistema externo

  • ORMs y acceso a datos

    • Entity Framework Core con LINQ-to-SQL y Migrations.
    • Dapper para consultas rápidas y control sobre SQL.
    • Prisma.NET (alternativa moderna multiplataforma).
  • Autenticación y seguridad

    • Identity Server para OAuth2 y OpenID Connect.
    • JWT para microservicios.
    • Encriptación de datos con DataProtectionProvider.
  • APIs y mensajería

    • gRPC para comunicación binaria eficiente.
    • SignalR para tiempo real (chats, dashboards).
    • MediatR para CQRS e inyección de comportamientos cross-cutting (logging, validaciones).

      Siguientes pasos y temas por expandir

  • Event Sourcing y CQRS con .NET
  • Saga Pattern y transacciones distribuidas
  • Testing distribuido entre microservicios
  • Optimización y profiling .NET
  • [[Reflexión y metaprogramación en C#]]
  • Interoperabilidad avanzada con C++ y Rust desde .NET
  • Desarrollo de librerías NuGet internas
  • Arquitectura hexagonal aplicada a .NET Core

.NET — Fundamentos complementarios y conceptos esenciales

Fundamentos del ecosistema .NET

1. CLR, BCL y compilación

  • CLR (Common Language Runtime)
    Es el motor de ejecución de .NET, responsable de:
    • Gestión de memoria (GC, heap, stack).
    • Seguridad y aislamiento de código (sandboxing, CAS).
    • Ejecución de código intermedio (IL) compilado a máquina nativa mediante JIT o AOT.
  • BCL (Base Class Library)
    Conjunto de namespaces fundamentales como:
    • System, System.IO, System.Collections, System.Threading, System.Net.
    • Proporciona estructuras base, colecciones, IO, red, threading, tareas y utilidades generales.
    • Facilita la interoperabilidad entre lenguajes soportados (C#, F#, VB.NET).
  • Compilación y despliegue
    • JIT (Just-in-Time): compila el código IL en tiempo de ejecución.
    • AOT (Ahead-of-Time): genera binarios nativos optimizados (ideal para entornos embebidos o contenedores).
    • Assembly (.dll o .exe): unidad de despliegue que incluye metadatos, IL y recursos.
    • NuGet: sistema de gestión de dependencias y distribución de paquetes.

2. Tipos, memoria y gestión

  • Tipos por valor y por referencia
    • Valor: struct, enum → almacenados en stack.
    • Referencia: class, interface, delegate, array → heap.
  • Garbage Collector (GC)
    • Administra la memoria automáticamente.
    • Generacional (Gen 0, 1, 2) para optimizar rendimiento.
    • Permite modos configurables (Server, Workstation, SustainedLowLatency).
  • Span<T> y Memory<T>
    • Acceso seguro y eficiente a datos sin copias adicionales.
    • Fundamentales en .NET moderno para optimización de rendimiento.

3. Asincronía y concurrencia

  • Task-based Asynchronous Pattern (TAP)
    Usa async / await para manejar I/O no bloqueante.
    • Task.Run() → ejecución paralela en pool de threads.
    • ValueTask → reduce overhead en operaciones rápidas o sincrónicas.
  • Parallelism & Threading
    • Parallel.For y Parallel.ForEach para procesamiento concurrente.
    • System.Threading.Channels para pipelines asincrónicos.
    • PLINQ para consultas paralelas sobre colecciones.

4. Configuración, logging y dependencia

  • Configuración flexible
    • appsettings.json, variables de entorno, secrets locales.
    • IConfiguration y IOptions<T> para inyección tipada.
  • Logging unificado
    • ILogger<T> integrado en todo el ecosistema.
    • Integraciones con Serilog, Seq, Application Insights.
  • Dependency Injection nativo
    • Registro mediante AddTransient, AddScoped, AddSingleton.
    • Compatible con IServiceProvider y decoradores dinámicos.

Fundamentos de desarrollo y despliegue

5. Entrada/salida y red

  • System.IO
    • Streams, archivos, directorios y buffers.
    • Asincronía con FileStream y StreamReader async.
  • Networking
    • HttpClient moderno, Sockets para bajo nivel.
    • System.Net.Http.Json para APIs REST.
    • gRPC para comunicación binaria optimizada entre microservicios.

6. Serialización y formatos

  • JSON
    • System.Text.Json por defecto: rápido, eficiente y tipado.
    • Newtonsoft.Json aún útil para escenarios complejos (polimorfismo, LINQ a JSON).
  • XML y BSON
    • System.Xml para configuraciones o compatibilidad legacy.
    • MongoDB.Bson para NoSQL.
  • Binary serialization
    • Usada en entornos controlados o para performance crítico.
    • Reemplazada en la mayoría de casos por JSON o MessagePack.

7. Entornos de ejecución y compatibilidad

  • .NET Standard
    • Abstracción que unificó APIs entre .NET Framework, .NET Core y Xamarin.
  • .NET Core → .NET 5+
    • Unificación completa del runtime.
    • Soporte multiplataforma real (Windows, Linux, macOS, ARM).
  • Frameworks especializados
    • ASP NET para web.
    • MAUI NET y xamarin para móvil.
    • Blazor para UI web con C#.
    • WPF y WinForms para escritorio clásico.

8. Seguridad y autenticación

  • Criptografía
    • System.Security.Cryptography incluye AES, RSA, HMAC.
    • Soporte para certificados X.509 y firma digital.
  • Identity y autenticación
    • ASP NET Identity para manejo de usuarios y roles.
    • JWT para APIs y microservicios.
    • OpenID Connect y OAuth2 con Identity Server o Azure AD.

9. Ecosistema de herramientas y flujo de trabajo

CLI y automatización

  • dotnet new, build, run, publish, test, pack.
  • Integración con CI/CD y Docker.
  • Scripts cross-platform (.NET tools globales y locales).

IDEs y editores

  • Visual Studio: entorno completo, debugger avanzado.
  • VS Code: ligero y multiplataforma.
  • JetBrains Rider: integración profunda con herramientas de análisis.

Testing

  • Unit Tests: xUnit, NUnit, MSTest.
  • Mocking: Moq, NSubstitute, FakeItEasy.
  • Integración y E2E: Playwright.NET, Selenium, WebApplicationFactory.
  • Coverage y pipelines: integración con Azure DevOps o GitHub Actions.

10. Ecosistema moderno y comunidad

  • NuGet y GitHub Packages para distribución de librerías.
  • Open Source en .NET: .NET runtime, Roslyn, ASP.NET Core, EF Core.
  • Comunidad activa: .NET Foundation, Microsoft Learn, Stack Overflow.
  • Actualizaciones frecuentes: releases semestrales con .NET 9 y versiones LTS (cada 2 años).

Siguientes expansiones recomendadas

  • Internals del CLR y JIT avanzado
  • Memoria, GC y optimización de heap
  • Patrones asincrónicos y concurrencia avanzada
  • Networking de alto rendimiento en .NET
  • Metaprogramación con Reflection y Source Generators
  • Creación de NuGet packages internos y versionado semántico
  • Desarrollo multiplataforma con MAUI y Blazor Hybrid
  • Infraestructura como código con .NET y Terraform

.NET — Temas avanzados y áreas complementarias

1. Internals del CLR y optimización avanzada

Ejecución interna del CLR

  • Metadata y Reflection
    • Cada Assembly contiene metadata tables que describen tipos, métodos y atributos.
    • System.Reflection permite inspección y creación dinámica de tipos en runtime.
    • Reflection.Emit y DynamicMethod permiten generar IL dinámico (útil en frameworks o proxies).
  • Runtime Generics
    • Generics se implementan mediante reification completa: los tipos genéricos existen en tiempo de ejecución.
    • Permite reflejar, instanciar y optimizar tipos genéricos con constraints (where T : class, etc.).
    • Reduce boxing/unboxing en colecciones tipadas (List<int> vs ArrayList).
  • Tiered Compilation
    • El CLR usa dos fases: compilación rápida y optimización progresiva.
    • Tier 0: código JIT rápido para inicio veloz.
      Tier 1: optimización posterior basada en perfilado (Hot Path JIT).
  • Profile-guided Optimization (PGO)
    • A partir de .NET 8, el runtime ajusta optimizaciones según ejecución real.
    • Permite mejoras automáticas de rendimiento en builds posteriores.

2. Memoria, GC y optimización del heap

  • Estructura de memoria
    • Stack: variables locales y llamadas.
    • Heap: objetos, closures, referencias.
    • LOH (Large Object Heap): bloques >85KB, liberados en GC completo.
    • Pinned Objects: evitan movimiento de memoria (útiles en interoperabilidad).
  • Técnicas de optimización
    • Evitar allocations innecesarias (usar Span, ArrayPool).
    • Reutilizar buffers (patrón Object Pooling con Microsoft.Extensions.ObjectPool).
    • Aplicar structs inmutables y readonly cuando sea posible.
    • Usar ValueTask y IAsyncEnumerable para reducir overhead asincrónico.

3. Concurrencia avanzada

  • Dataflow y actores
    • System.Threading.Tasks.Dataflow: modelo de bloques (producer-consumer, pipelines).
    • Implementación de patrones actor-like para procesamiento concurrente sin locks.
  • Async Streams
    • await foreach en IAsyncEnumerable<T> permite flujos asincrónicos continuos.
  • Synchronization Context
    • Controla cómo se programan tareas (UI thread, web context, etc.).
    • Útil para integrar tareas background con ASP NET o MAUI NET sin bloquear.

4. Networking de alto rendimiento

  • Sockets y pipelines
    • System.IO.Pipelines: base interna de Kestrel y SignalR, optimiza I/O sin copias.
    • SocketAsyncEventArgs para operaciones masivas de red sin crear objetos.
  • HTTP/3 y QUIC
    • Soporte en .NET 8+ para HTTP/3 (más rápido, seguro y basado en UDP).
  • MessagePack y gRPC
    • MessagePack: serialización binaria ultrarrápida.
    • gRPC: comunicación tipo RPC con contratos .proto, ideal para microservicios.

5. Metaprogramación y generación de código

  • Reflection y atributos
    • Atributos personalizados para metadata declarativa ([Authorize], [CustomMapping]).
    • Inspección y ejecución dinámica según decoradores.
  • Source Generators
    • Ejecutan en compilación para generar código estático.
    • Usados en frameworks modernos (por ejemplo, System.Text.Json genera serializadores a compile-time).
    • Mejora rendimiento evitando reflection runtime.
  • Roslyn APIs
    • Permiten análisis y transformación de código fuente (linting, refactoring, tooling interno).

6. Extensibilidad e interoperabilidad

  • Interop con C++
    • DllImport y extern para llamar funciones nativas (P/Invoke).
    • C++/CLI para integración profunda y gestión mixta.
  • Interop con Rust
    • Comunicación vía FFI (extern "C") usando unsafe y Marshal.
  • COM Interop
    • Uso de librerías legacy (Office, Windows Shell) desde .NET moderno.
  • Embeddings
    • .NET embebido dentro de motores C++ o Python con hostfxr y nethost.

7. Infraestructura y despliegue

  • Infraestructura como código (IaC)
    • Integración con Terraform, Pulumi o Bicep mediante SDKs .NET.
  • Observabilidad
    • Logging estructurado (Serilog), métricas (Prometheus .NET exporters), tracing (OpenTelemetry).
  • Diagnóstico
    • dotnet-counters, dotnet-trace, dotnet-dump para profiling live.
    • PerfView para inspeccionar GC, CPU y memoria.
  • Hot Reload
    • Permite edición en tiempo real sin recompilar completamente (productividad alta en UI y API).

8. Multiplataforma y dispositivos

  • MAUI avanzado
    • Integración nativa con sensores, Bluetooth, cámara y almacenamiento.
    • Soporte para Blazor Hybrid: web + nativo en una misma app.
  • WebAssembly y Blazor WASM
    • Ejecución directa en navegador, sin servidor.
    • Integración con APIs JS mediante IJSRuntime.
  • IoT y .NET nanoFramework
    • Framework liviano para microcontroladores (.NET CLR reducido).
    • Uso de System.Device.Gpio para hardware Raspberry Pi, ESP32, etc.

9. Cloud-native y resiliencia

  • Resiliencia
    • Políticas de reintento, fallback y circuit breaker con Polly.
    • Integración de resiliencia automática en HttpClientFactory.
  • Distribución y mensajería
    • RabbitMQ, Azure Service Bus, Kafka mediante librerías oficiales.
    • Event-driven architecture con MassTransit, Rebus o NServiceBus.
  • Serverless
    • Azure Functions o AWS Lambda con runtime .NET nativo.
    • Ejecución basada en eventos y despliegue inmediato desde CLI.

10. Prácticas de ingeniería y calidad

  • Versionado y mantenimiento
    • LTS (Long Term Support) y Current releases: planificar migraciones.
    • Semantic Versioning (SemVer) aplicado a NuGet.
  • Performance Testing
    • BenchmarkDotNet para microbenchmarks reproducibles.
  • Code Quality
    • Análisis estático con Roslyn Analyzers.
    • Uso de convenciones StyleCop, FxCop, .editorconfig.
  • Documentación
    • docfx o Sandcastle para generar documentación a partir de XML docs.

11. Integración con otros lenguajes y ecosistemas

  • Python y R
    • Comunicación vía REST, gRPC o con Python.NET.
  • JavaScript
    • Interoperabilidad directa en Blazor WASM o mediante SignalR.
  • Java
    • Uso de IKVM.NET (histórico) o integración por API Gateway.
  • SQL y NoSQL
    • Conectores nativos para SQL Server, PostgreSQL, MongoDB, Redis, Cassandra.
    • LINQ-to-Entities y LINQ-to-Objects para consultas tipadas.

12. Pruebas distribuidas y sistemas complejos

  • Tests de integración entre microservicios
    • Contenedores de prueba con Testcontainers.NET.
    • Mock de colas y buses de mensajes.
  • Contratos y validación
    • Pact Testing (Consumer-Driven Contracts).
    • Validaciones automáticas con FluentValidation y DataAnnotations.

Siguientes pasos y notas relacionadas

  • Patrones Enterprise en .NET
  • Event Driven Architecture con MassTransit
  • Source Generators y metaprogramación práctica
  • Profiling y optimización .NET con PerfView y BenchmarkDotNet
  • Desarrollo híbrido con MAUI + Blazor
  • Implementación de resiliencia avanzada con Polly y HttpClientFactory
  • Creación de SDKs y librerías NuGet internas
  • Diagnóstico de memoria y GC tuning en producción

.NET — Extensión completa de temas especializados

1. Ecosistema empresarial y arquitectura organizacional

Arquitectura orientada a dominios amplios (DDD + Enterprise)

  • Bounded Contexts: cada módulo del negocio tiene su propio modelo y lógica interna, comunicándose mediante eventos o APIs.
  • Anti-Corruption Layer (ACL): capa intermedia que evita acoplar dominios heterogéneos.
  • Domain Events y Event Bus: coordinación asíncrona entre módulos o microservicios.
  • Specification Pattern: encapsula consultas de negocio complejas reutilizables (ideal para Entity Framework Core).

Monitoreo de ecosistemas distribuidos

  • Telemetría unificada con OpenTelemetry:
    • Tracing: seguimiento de peticiones a través de microservicios.
    • Metrics: consumo de CPU, memoria, latencia, throughput.
    • Logs correlacionados con Activity.Current y ILogger.

Estrategias de migración empresarial

  • Migrar desde NET Framework a .NET moderno:
    • Análisis con try-convert o Upgrade Assistant.
    • Uso de Compatibility Shim Packages.
    • Modularización progresiva y despliegue híbrido (.NET Core + Framework coexistentes).

2. Data Engineering y procesamiento masivo

Acceso y persistencia avanzada

  • EF Core avanzado
    • Soporte para Temporal Tables (auditoría histórica).
    • Raw SQL y Interpolated Queries seguras.
    • Value Converters para tipos personalizados (ej. Currency, Email).
  • ORM alternativos
    • Dapper para queries manuales de alto rendimiento.
    • Linq2Db y RepoDB para acceso directo con LINQ optimizado.
  • Caching
    • IMemoryCache, DistributedCache, y Redis con StackExchange.Redis.
    • Patrón Cache Aside para mejorar tiempos de respuesta.

Data Processing

  • Parallel Data Pipelines
    • Uso de Channels, TPL Dataflow o IAsyncEnumerable para ETL interno.
  • Integración con sistemas de Big Data
    • Conectores hacia Kafka, Spark, o Data Lake con SDKs .NET.
  • Batch y scheduling
    • Hangfire para tareas programadas persistentes.
    • Quartz.NET para orquestación temporal distribuida.

3. DevOps, observabilidad y despliegue continuo

CI/CD avanzado

  • Build Pipelines
    • GitHub Actions, Azure DevOps, GitLab CI.
    • Estrategia de versiones automáticas (tags, commits, branches).
  • Deployment Targets
    • Docker registries, Azure Web Apps, AWS ECS/Fargate, Kubernetes.
    • Publicación multi-stage con YAML pipelines.
  • Infraestructura reproducible
    • Terraform + .NET SDK.
    • Pulumi con C# o F# para declarar infraestructura como código.

Observabilidad extendida

  • Tracing distribuido
    • Correlación de peticiones con ActivitySource.
    • Visualización en Jaeger, Zipkin o Application Insights.
  • Alertas y dashboards
    • Métricas exportadas con Prometheus .NET SDK.
    • Integración con Grafana para observación centralizada.

4. Seguridad avanzada

Autenticación y autorización

  • Claims-based Authentication con ClaimsPrincipal y ClaimsIdentity.
  • Role-based Access Control (RBAC) nativo en ASP NET.
  • Policies y Requirements para reglas complejas.
  • IdentityServer + Duende para OAuth2/OpenID Connect completo.

Cifrado, firma y secretos

  • Protección de datos
    • DataProtectionProvider integrado en ASP.NET.
    • Rotación automática de claves.
  • Certificados y firma
    • Creación de X509 con System.Security.Cryptography.X509Certificates.
    • Validación de firma y timestamp en documentos.
  • Secrets y credenciales
    • dotnet user-secrets en desarrollo.
    • Azure Key Vault o AWS Secrets Manager en producción.

5. Testing distribuido, QA y performance

Estrategias de pruebas

  • Pruebas de carga y estrés
    • NBomber, k6, o JMeter con endpoints .NET.
  • Testcontainers.NET
    • Ejecución de bases de datos y colas en contenedores efímeros para integración realista.
  • Pact Testing
    • Contratos Consumer-Driven entre servicios REST/gRPC.
  • Mutation Testing
    • Stryker.NET para asegurar cobertura de lógica.

Benchmarking

  • BenchmarkDotNet para microbenchmarking.
  • dotnet-trace y PerfView para profiling detallado.
  • EventPipe para análisis de eventos runtime (GC, CPU, ThreadPool).

6. Cloud-native y Serverless

Microservicios escalables

  • Despliegue en Kubernetes:
    • Autoescalado horizontal con HPA.
    • ConfigMaps y Secrets para configuración segura.
  • Service Mesh (Istio, Linkerd):
    • Tráfico seguro, métricas y resiliencia a nivel red.
  • Event-driven con CloudEvents:
    • Integración nativa en Azure Event Grid o AWS EventBridge.

Serverless

  • Azure Functions / AWS Lambda con .NET
    • Cold start reducido con .NET AOT.
    • Integración con colas, triggers y timers.
  • Durable Functions
    • Workflow as code (sagas y orquestaciones distribuidas).

7. Inteligencia artificial, análisis y automatización

IA con .NET

  • ML.NET
    • Entrenamiento y consumo de modelos ML sin depender de Python.
    • Clasificación, regresión, detección de anomalías, recomendadores.
  • ONNX Runtime
    • Ejecución de modelos preentrenados (PyTorch, TensorFlow) en .NET.
  • Integración con OpenAI, Hugging Face
    • Consumo de APIs de IA desde .NET con clientes HTTP o SDKs oficiales.
  • AI + Office Automation
    • Generación automática de reportes Excel o Word integrando ML.NET + ClosedXML o Aspose.Cells for .NET.

8. Frontend y UX en el ecosistema .NET

Blazor

  • Blazor Server: renderizado en servidor vía SignalR.
  • Blazor WASM: ejecución completa en navegador con WebAssembly.
  • Blazor Hybrid (MAUI): UI combinada web + nativa.
  • Componentización avanzada
    • Reutilización entre proyectos.
    • Comunicación por EventCallback y CascadingParameter.

Integración con frameworks externos

  • Angular, React, Vue
    • API REST + JWT gestionado desde ASP NET.
    • SSR híbrido (Angular Universal o React Static con .NET backend).
  • Interoperabilidad JS
    • IJSRuntime y JSObjectReference en Blazor.

9. Ecosistema extendido

Lenguajes soportados

  • C#
    • Lenguaje principal, multiparadigma (OO, FP, asincronía nativa).
  • F#
    • Funcional puro, ideal para pipelines, data y testing.
  • VB.NET
    • Mantenido para soporte legacy y entornos administrativos.
  • PowerShell
    • Automatización avanzada y scripting con .NET Core Runtime.
  • C++/CLI
    • Interoperabilidad directa con código nativo.

Frameworks especializados

  • Orleans
    • Modelo actor distribuido para sistemas reactivos y escalables.
  • Akka.NET
    • Implementación de actores para concurrencia segura y resiliente.
  • MassTransit / Rebus
    • Mensajería distribuida con sagas, retries, y middleware integrable.
  • GraphQL for .NET
    • API declarativas con resolvers y esquemas tipados.

10. Ecosistema de productividad y automatización

Generación de documentación

  • docfx para portales técnicos.
  • Swashbuckle (Swagger/OpenAPI) para endpoints.
  • NSwag para generar clientes TypeScript o C# desde APIs.

Herramientas de mantenimiento

  • dotnet-format para estilo y convención.
  • Roslyn analyzers y StyleCop para inspección automática.
  • Dependabot o Renovate para actualizar dependencias.

Automatización interna

  • Code Generators y Templates
    • dotnet new --install para scaffolding personalizado.
    • Integración con T4 y Source Generators para boilerplate.
  • Builds reproducibles
    • MSBuild y YAML pipelines con versiones fijadas.
    • Caché de dependencias y artefactos con nuget.config.

11. Temas para expansión futura

  • IA generativa e integración con ML.NET y ONNX
  • Arquitecturas distribuidas orientadas a eventos
  • Interoperabilidad avanzada con Rust y WebAssembly
  • Automatización y scripting con PowerShell y .NET CLI
  • Diseño de SDKs empresariales y clientes gRPC internos
  • Estrategias de resiliencia y escalado dinámico en Kubernetes
  • Sistemas actor con Orleans y Akka.NET
  • Integración avanzada de .NET con Big Data y Spark
  • Ejecución AOT y compilación cruzada para IoT y edge computing

🧠 .NET Programming CheatSheet

⚙️ Comandos básicos CLI

# Crear proyecto
dotnet new console -n MiApp  
dotnet new webapi -n MiApi  
dotnet new maui -n MiAppMaui  

# Ejecutar y compilar
dotnet run  
dotnet build  
dotnet watch run  

# Gestionar dependencias
dotnet add package Newtonsoft.Json  
dotnet restore  

# Testing
dotnet test  

# Publicar (para Docker o servidor)
dotnet publish -c Release -r linux-x64  

`


🧩 Estructura típica de un proyecto .NET

/MiProyecto
	/Controllers
	/Models
	/Services
	/Data
	wwwroot/
	appsettings.json
	Program.cs

🧱 Sintaxis esencial C#

// Variables y tipos
int edad = 30;
string nombre = "Edu";
bool activo = true;

// Condicionales
if (edad > 18) Console.WriteLine("Adulto");
else Console.WriteLine("Menor");

// Bucles
for (int i = 0; i < 10; i++) Console.WriteLine(i);
foreach (var item in lista) Console.WriteLine(item);

// Métodos
int Sumar(int a, int b) => a + b;

// Clases y objetos
public class Persona
{
	public string Nombre { get; set; }
	public void Saludar() => Console.WriteLine($"Hola, soy {Nombre}");
}

🧠 Funcional y LINQ

var numeros = new List<int> {1,2,3,4,5};
var pares = numeros.Where(n => n % 2 == 0)
                   .Select(n => n * 10)
                   .ToList();

int suma = numeros.Aggregate((a,b) => a + b);

🗂️ Archivos y JSON

using System.IO;
using System.Text.Json;

var texto = File.ReadAllText("data.txt");
var objeto = JsonSerializer.Deserialize<MiClase>(texto);
File.WriteAllText("salida.json", JsonSerializer.Serialize(objeto));

💉 Dependency Injection

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddScoped<IUserService, UserService>();
var app = builder.Build();

app.MapGet("/users", (IUserService service) => service.GetAll());
app.Run();

🌐 Minimal API

var app = WebApplication.Create();
app.MapGet("/", () => "Hello .NET!");
app.MapPost("/echo", (string msg) => $"Echo: {msg}");
app.Run();

🧱 Entity Framework Core

public class AppDbContext : DbContext
{
	public DbSet<User> Users { get; set; }
}

public class User { public int Id { get; set; } public string Name { get; set; } }

Migraciones y base de datos

dotnet ef migrations add Init  
dotnet ef database update

Consulta básica

using var db = new AppDbContext();
var users = db.Users.Where(u => u.Name.Contains("Ana")).ToList();

🧰 Testing con xUnit

public class CalculatorTests
{
	[Fact]
	public void Add_ReturnsCorrectSum()
	{
		Assert.Equal(4, new Calculator().Add(2,2));
	}
}

⚡ Asincronía y tareas

async Task DescargarAsync()
{
	var http = new HttpClient();
	var data = await http.GetStringAsync("https://api.example.com");
	Console.WriteLine(data);
}

🔄 Manejo de errores

try
{
	var result = 10 / 0;
}
catch (DivideByZeroException ex)
{
	Console.WriteLine(ex.Message);
}
finally
{
	Console.WriteLine("Finalizado");
}

🐳 Docker + .NET

FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS base
WORKDIR /app
COPY . .
ENTRYPOINT ["dotnet", "MiApp.dll"]
docker build -t miappnet .
docker run -p 8080:80 miappnet

🔐 Autenticación básica con JWT

builder.Services.AddAuthentication("Bearer")
	.AddJwtBearer(options =>
	{
		options.TokenValidationParameters = new()
		{
			ValidateIssuer = true,
			ValidIssuer = "miapp",
			ValidateAudience = false,
			IssuerSigningKey = new SymmetricSecurityKey(
				Encoding.UTF8.GetBytes("clave-secreta-super-segura"))
		};
	});

🧾 Logging y configuración

builder.Logging.ClearProviders();
builder.Logging.AddConsole();

var config = builder.Configuration;
string conn = config.GetConnectionString("DefaultConnection");

📦 Serialización y utilidades

var json = JsonSerializer.Serialize(objeto, new JsonSerializerOptions { WriteIndented = true });
var anon = new { Id = 1, Nombre = "Edu" };

🧭 Recursos útiles

🧠 .NET Programming CheatSheet II — Avanzado

🧩 Arquitectura avanzada

  • Clean Architecture (ampliado)
    • Capas principales:
      • Domain: entidades, value objects, eventos de dominio.
      • Application: lógica de negocio, casos de uso, servicios.
      • Infrastructure: acceso a datos, servicios externos.
      • Presentation: API, UI o endpoints.
    • Reglas: las dependencias siempre apuntan hacia el dominio.
  • CQRS y MediatR
    • Separación de comandos y consultas.
    • IRequest<T> y IRequestHandler<TRequest, TResponse>.
    • Ideal con MediatR para inyección automática de handlers.
public record GetUsersQuery() : IRequest<IEnumerable<User>>;

public class GetUsersHandler : IRequestHandler<GetUsersQuery, IEnumerable<User>>
{
	private readonly AppDbContext _db;
	public GetUsersHandler(AppDbContext db) => _db = db;

	public async Task<IEnumerable<User>> Handle(GetUsersQuery request, CancellationToken ct)
		=> await _db.Users.ToListAsync(ct);
}

`


🪶 Reflection y metaprogramación

var type = typeof(User);
foreach (var prop in type.GetProperties())
	Console.WriteLine($"{prop.Name} : {prop.PropertyType}");
  • Use cases:

    • Serialización personalizada.
    • Mapping dinámico entre DTOs.
    • Creación de plug-ins y carga de ensamblados en tiempo de ejecución (Assembly.LoadFrom()).

🧵 Programación concurrente

Parallel.For(0, 10, i => Console.WriteLine(i));
await Task.WhenAll(
	DownloadAsync("a"), 
	DownloadAsync("b")
);
  • TPL (Task Parallel Library) para paralelismo de alto nivel.
  • Concurrent collections: ConcurrentDictionary, BlockingCollection.
  • Channels para pipelines y colas internas (System.Threading.Channels).

🌐 gRPC y comunicación entre servicios

  • gRPC: protocolo binario de alta eficiencia entre microservicios.
  • Definir .proto:
service UserService {
	rpc GetUser (UserRequest) returns (UserReply);
}
  • Generar código con Grpc.Tools.
  • Ideal para comunicación entre servicios .NET o entre lenguajes.

🕸️ SignalR — comunicación en tiempo real

app.MapHub<ChatHub>("/chat");
  • Permite comunicación bidireccional en webs y apps MAUI.
  • Escenarios: chats, dashboards, actualizaciones en vivo.
  • Compatible con WebSockets, SSE y Long Polling.

📡 Integración con APIs externas

var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer token");
var data = await client.GetFromJsonAsync<Usuario>("https://api.miapp.com/users/1");
  • Typed Clients: inyección nativa en DI.
  • Polly: políticas de resiliencia (reintentos, circuit breakers).

🧰 Logging avanzado

  • Serilog

    • En Program.cs:
  Log.Logger = new LoggerConfiguration()
  	.WriteTo.Console()
  	.WriteTo.File("logs/log-.txt", rollingInterval: RollingInterval.Day)
  	.CreateLogger();
  • Enriquecedores para incluir contexto (usuario, requestId).
  • Seq o Grafana Loki para visualizar logs distribuidos.

🧮 Background Services y Hosted Workers

public class Worker : BackgroundService
{
	protected override async Task ExecuteAsync(CancellationToken ct)
	{
		while (!ct.IsCancellationRequested)
		{
			Console.WriteLine("Running task...");
			await Task.Delay(1000, ct);
		}
	}
}
  • Ideal para tareas programadas o listeners de colas.
  • Regístralos con builder.Services.AddHostedService<Worker>();.

💾 Caching y rendimiento

  • IMemoryCache para caché en memoria local.
  • DistributedCache con Redis.
builder.Services.AddStackExchangeRedisCache(options =>
	options.Configuration = "localhost:6379");
  • Uso de OutputCache en endpoints para optimización de respuestas.
  • Profiling con dotnet-trace, dotnet-counters, PerfView.

🧱 Integración con bases de datos NoSQL

  • MongoDB
  var client = new MongoClient("mongodb://localhost:27017");
  var db = client.GetDatabase("test");
  var users = db.GetCollection<User>("Users");
  await users.InsertOneAsync(new User { Name = "Ana" });
  • CosmosDB (Azure) con SDK oficial.
  • LiteDB para persistencia embebida en aplicaciones locales.

🔐 Seguridad avanzada

  • Data Protection API
  var provider = DataProtectionProvider.Create("MiApp");
  var protector = provider.CreateProtector("Credenciales");
  var encriptado = protector.Protect("clave");
  • Autorización basada en políticas

    • [Authorize(Policy = "AdminOnly")]
    • builder.Services.AddAuthorization(o => o.AddPolicy("AdminOnly", p => p.RequireRole("Admin")));
  • Rate Limiting Middleware

  builder.Services.AddRateLimiter(_ => _.AddFixedWindowLimiter("default",
  	options => { options.PermitLimit = 5; options.Window = TimeSpan.FromSeconds(10); }));

🧩 Modularidad y plugins dinámicos

  • Cargar ensamblados externos:
var asm = Assembly.LoadFrom("MiPlugin.dll");
var type = asm.GetType("MiPlugin.Plugin");
dynamic instance = Activator.CreateInstance(type);
instance.Run();
  • Útil para aplicaciones extensibles o sistemas de scripts.

⚙️ Interoperabilidad nativa

  • C++/CLI y P/Invoke
  [DllImport("kernel32.dll")]
  static extern bool Beep(int freq, int dur);
  • Comunicación con cpp y librerías nativas.
  • Rust o Python interoperables mediante procesos externos o bindings.

🧱 Publicación y despliegue

dotnet publish -c Release -r win-x64 --self-contained true
  • Opciones:

    • --self-contained: incluye el runtime.
    • -p:PublishSingleFile=true: genera un único ejecutable.
    • -p:PublishTrimmed=true: elimina dependencias no usadas.
  • Despliegue en Docker, Azure, AWS Lambda o Kubernetes.


📦 NuGet y distribución

dotnet pack -c Release
dotnet nuget push bin/Release/MiLib.1.0.0.nupkg -k API_KEY -s https://api.nuget.org/v3/index.json
  • Crear librerías reutilizables internas.
  • Usar Directory.Build.props para configuración global.

🧭 Temas adicionales a explorar

  • Source Generators en .NET
  • Roslyn Analyzers personalizados
  • Performance Tuning con Span y Memory
  • .NET AOT y Native Compilation
  • Dynamic LINQ y Expression Trees
  • Testing distribuido y contenedores de prueba
  • Integración avanzada con Azure Functions y Service Bus

🚀 Tendencias .NET 2025

🌍 Visión general

El ecosistema .NET en 2025 refleja un salto hacia la eficiencia, la inteligencia y la unificación del desarrollo multiplataforma. Las tendencias actuales combinan rendimiento nativo, IA integrada, seguridad avanzada y desarrollo orientado al edge computing.
Esta guía sintetiza las líneas más relevantes sin repetir notas previas, enfocándose en evolución, herramientas y estrategias para adoptar estas tendencias.


⚙️ 1. Compilación AOT (Ahead-of-Time) y rendimiento extremo

  • NativeAOT consolida la tendencia hacia ejecutables nativos sin dependencia del runtime.
    • Ideal para microservicios, apps serverless y entornos edge.
    • Reduce startup time, consumo de memoria y tamaño del despliegue.
  • AOT híbrido combina rendimiento nativo con depuración JIT cuando se necesita.
  • Herramientas: dotnet publish -p:PublishAot=true, dotnet-native.
  • Se integra con optimizaciones como TrimMode=link para eliminar código no usado.

📎 Ver también: .NET AOT y Native Compilation · Performance Tuning con Span y Memory


💻 2. Desarrollo multiplataforma unificado

  • .NET MAUI madura como framework completo para móvil, escritorio y web híbrido.
  • Blazor Hybrid permite compartir lógica entre UI y backend sin JavaScript.
  • Visual Studio 2025 integra plantillas unificadas que soportan web + MAUI + gRPC.
  • Se consolida la tendencia Full-Stack .NET: un solo lenguaje (C#) para todo el ciclo.

📎 Relacionado: MAUI NET · Blazor · xamarin


🧠 3. Integración con IA y Machine Learning

  • ML.NET 3.0 amplía soporte para modelos ONNX y PyTorch.
  • Nuevas APIs simplifican el uso de IA generativa en .NET (Azure OpenAI, Hugging Face).
  • Integración natural con .NET Aspire, el stack para intelligent cloud-native apps.
  • Tendencia: “AI-embedded apps”, donde la IA forma parte de la lógica de negocio.

Ejemplo:

var prediction = mlModel.Predict(new InputData { Text = "Consulta del usuario" });

`

📎 Ver también: Integración IA en .NET · Azure Cognitive Services


☁️ 4. Arquitecturas cloud-native y microservicios

  • .NET se orienta aún más al entorno nativo en la nube:

    • Integración directa con Kubernetes, Dapr, y Azure Container Apps.
    • Soporte AOT en imágenes base de mcr.microsoft.com/dotnet/aspnet:9.0.
  • Patrones dominantes:

    • Event-driven architecture.
    • Saga Pattern y Outbox Pattern para consistencia distribuida.
  • Se priorizan despliegues ligeros con observabilidad integrada (OpenTelemetry).

📎 Ver: Saga Pattern y transacciones distribuidas · Docker · Kubernetes


🧩 5. Seguridad avanzada y cumplimiento

  • Zero Trust y autenticación federada son el nuevo estándar.
  • .NET refuerza seguridad de APIs mediante:

    • Microsoft.Identity.Web con Azure AD.
    • Políticas de autorización personalizables y claims dinámicos.
  • Supply Chain Security:

    • Verificación de paquetes con firmas (dotnet nuget verify).
    • Escaneo de dependencias (dotnet list package --vulnerable).

📎 Referencias: Autenticación y seguridad · Identity Server


🧰 6. Productividad y experiencia del desarrollador (DX)

  • Hot Reload mejorado y scaffolding dinámico.
  • C# 13 introduce nuevas construcciones:

    • Primary constructors for classes.
    • Discriminated unions.
    • Collection expressions simplificadas.
  • .NET Aspire ofrece entornos locales reproducibles con dashboards y telemetría nativa.
  • Mayor integración entre CLI y DevOps: dotnet new webapi --use-serilog --use-swagger

📎 Relacionado: CI CD · Roslyn Analyzers personalizados


🔋 7. Sostenibilidad y eficiencia operativa

  • Prioridad a reducir coste en la nube y huella energética.
  • AOT, pooling de conexiones y GC adaptativo reducen consumo.
  • Surgen herramientas como GreenOps Analyzer para medir impacto energético.
  • KPI emergente: Watts per Request (WPR).

📎 Ver: Optimización y profiling .NET · Performance Tuning con Span y Memory


🧱 8. Edge computing e IoT inteligente

  • Expansión de .NET hacia dispositivos y entornos desconectados.
  • .NET nanoFramework y .NET for IoT soportan microcontroladores ARM.
  • Azure IoT Edge + .NET 9 AOT permite despliegues ligeros y seguros en dispositivos industriales.
  • Integración con sensores, actuadores y servicios cloud.

📎 Ver: IoT con .NET · Integración con hardware y serial ports


🎮 9. .NET en nuevos dominios: juegos, XR y simulación

  • Integración creciente con motores de juego como Godot 4 C# y Stride Engine.
  • Se fomenta el uso de .NET para realidad aumentada (AR/XR) con MAUI + Unity Bridge.
  • En simulaciones industriales, .NET se usa junto con Blazor WebGPU y ComputeSharp.
  • Extiende el alcance de C# a mundos antes reservados a C++.

📎 Referencias: cpp · ComputeSharp · Shaders en .NET


🔮 10. Nuevos horizontes: metaprogramación, análisis y generación de código

  • Source Generators 3.0 permiten generar código de alto rendimiento durante la compilación.
  • Roslyn Analyzers evolucionan para aplicar linting dinámico, refactors automáticos y code fixes asistidos por IA.
  • Surgen frameworks como DotNetGen para crear SDKs internos basados en plantillas.

📎 Ver: Source Generators en .NET · [[Reflexión y metaprogramación en C#]]


🧭 Conclusión

El .NET de 2025 consolida su madurez empresarial y su expansión a nuevas áreas: inteligencia, rendimiento, sostenibilidad y unificación multiplataforma. Los equipos que adopten estas tendencias lograrán software más rápido, seguro y preparado para el futuro. La clave no está solo en usar .NET, sino en diseñar con visión cloud-native, IA-embedded y sostenibilidad desde el inicio.

📎 Siguientes notas:

  • Arquitectura Cloud-Native con .NET
  • AOT y rendimiento extremo en microservicios
  • IA aplicada en .NET con ML.NET y Cognitive Services
  • Zero Trust y seguridad avanzada en ASP.NET Core
  • .NET 9 — Cambios de lenguaje y nuevas APIs

🔥🔥🔥 MODULOS PRACTICOS net 9


🧱 Módulo 1 – Entorno Productivo Moderno .NET 9 (2025)


🎯 Objetivo

Configurar un entorno de desarrollo .NET 9 moderno, estable y preparado para proyectos reales, con tooling actualizado, productividad, testing y despliegue.


🧰 Requisitos previos

  • 🧩 SDK: .NET 9 SDK
  • 🧠 IDE: Visual Studio 2022 / JetBrains Rider / VS Code
  • 🐳 Docker Desktop (para contenedores)
  • 🔍 Postman o HTTPie (para probar APIs)
  • 🧾 Git y GitHub CLI (gh)

🏗️ Creación de un entorno base

# Crear una carpeta raíz para proyectos .NET
mkdir ~/Projects/dotnet2025
cd ~/Projects/dotnet2025

# Inicializar repositorio
git init
dotnet new globaljson --sdk-version 9.0.100
dotnet --info

`


🧩 Estructura recomendada para proyectos reales

/src
	/MyApp.Api
	/MyApp.Application
	/MyApp.Domain
	/MyApp.Infrastructure
/tests
	/MyApp.Tests

🧭 Mantén la estructura modular desde el inicio. Evita mezclar controladores, entidades y lógica en un mismo proyecto.


🪄 Crear la base API limpia

dotnet new webapi -n MyApp.Api
cd MyApp.Api
dotnet run

👉 Accede a: https://localhost:5001/swagger


⚙️ Configuración esencial

Program.cs

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
	app.UseSwagger();
	app.UseSwaggerUI();
}

app.MapControllers();
app.Run();

✅ Mantén este Program.cs minimalista; luego añadiremos capas y DI real.


🧱 Añadir herramientas de productividad

dotnet tool install -g dotnet-ef
dotnet tool install -g dotnet-outdated-tool
dotnet tool install -g dotnet-format
dotnet tool install -g dotnet-watch

Verificación

dotnet ef --version
dotnet format --check
dotnet watch run

🔍 Linter, Analyzer y estilo de código

  1. Agrega archivo .editorconfig en la raíz:
[*.cs]
indent_size = 4
dotnet_style_qualification_for_field = false:suggestion
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
dotnet_style_null_propagation = true:suggestion
  1. Activa Analyzers:
dotnet new editorconfig
dotnet build -warnaserror

🧩 Configuración de GitHub y CI inicial

gh repo create myapp-dotnet --public
git add .
git commit -m "chore: init .NET 9 project"
git push -u origin main

Ejemplo básico de workflow CI (.github/workflows/build.yml)

name: .NET Build

on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Setup .NET
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: 9.0.x
      - run: dotnet restore
      - run: dotnet build --no-restore
      - run: dotnet test --no-build --verbosity normal

🧠 Buenas prácticas iniciales

  • Usa nombres de proyectos y namespaces coherentes (ej. Company.Product.Layer).
  • Commits semánticos: feat:, fix:, chore:, test:, refactor:.
  • Automatiza dotnet restore, format, y test en CI antes del merge.

✅ Resultado esperado

✔️ Entorno moderno listo ✔️ Proyecto API ejecutándose en .NET 9 ✔️ GitHub + CI funcional ✔️ Herramientas instaladas para productividad


⚡ Módulo 2 – API REST limpia desde cero (ASP.NET Core 9)

🎯 Objetivo

Construir una API REST limpia, modular y mantenible, aplicando buenas prácticas modernas de .NET 9, con capas separadas, validaciones y un ejemplo funcional completo.


🏗️ Estructura del proyecto

En la raíz de tu workspace:

cd src
dotnet new webapi -n MyApp.Api
dotnet new classlib -n MyApp.Application
dotnet new classlib -n MyApp.Domain
dotnet new classlib -n MyApp.Infrastructure

`

Vincula las referencias:

cd MyApp.Api
dotnet add reference ../MyApp.Application
dotnet add reference ../MyApp.Domain
dotnet add reference ../MyApp.Infrastructure

Estructura:

/src
	/MyApp.Api
		/Controllers
		MyApp.Api.csproj
	/MyApp.Application
		/Services
	/MyApp.Domain
		/Entities
	/MyApp.Infrastructure
		/Data

🧩 Dominio: entidad base y ejemplo

MyApp.Domain/Entities/Product.cs

namespace MyApp.Domain.Entities;

public class Product
{
	public Guid Id { get; set; } = Guid.NewGuid();
	public required string Name { get; set; }
	public decimal Price { get; set; }
	public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
}

🧠 Capa de aplicación

MyApp.Application/Services/ProductService.cs

using MyApp.Domain.Entities;

namespace MyApp.Application.Services;

public interface IProductService
{
	IEnumerable<Product> GetAll();
	Product Add(Product product);
}

public class ProductService : IProductService
{
	private readonly List<Product> _products = [];

	public IEnumerable<Product> GetAll() => _products;

	public Product Add(Product product)
	{
		_products.Add(product);
		return product;
	}
}

🌐 API – Controlador principal

MyApp.Api/Controllers/ProductController.cs

using Microsoft.AspNetCore.Mvc;
using MyApp.Application.Services;
using MyApp.Domain.Entities;

namespace MyApp.Api.Controllers;

[ApiController]
[Route("api/[controller]")]
public class ProductController : ControllerBase
{
	private readonly IProductService _service;

	public ProductController(IProductService service)
	{
		_service = service;
	}

	[HttpGet]
	public IActionResult GetAll() => Ok(_service.GetAll());

	[HttpPost]
	public IActionResult Create([FromBody] Product product)
	{
		if (string.IsNullOrWhiteSpace(product.Name) || product.Price <= 0)
			return BadRequest("Invalid product data.");

		var created = _service.Add(product);
		return CreatedAtAction(nameof(GetAll), new { id = created.Id }, created);
	}
}

⚙️ Inyección de dependencias

MyApp.Api/Program.cs

using MyApp.Application.Services;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

// DI
builder.Services.AddSingleton<IProductService, ProductService>();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
	app.UseSwagger();
	app.UseSwaggerUI();
}

app.MapControllers();
app.Run();

🔍 Pruebas rápidas con cURL o HTTPie

# Obtener todos los productos
http GET https://localhost:5001/api/product

# Crear nuevo producto
http POST https://localhost:5001/api/product name="Teclado" price:=49.99

🧪 Añadir primer test (opcional)

tests/MyApp.Tests/ProductServiceTests.cs

using MyApp.Application.Services;
using MyApp.Domain.Entities;
using Xunit;

public class ProductServiceTests
{
	[Fact]
	public void Add_ShouldReturnProduct()
	{
		var service = new ProductService();
		var product = new Product { Name = "Mouse", Price = 25 };

		var result = service.Add(product);

		Assert.Equal("Mouse", result.Name);
		Assert.True(result.Id != Guid.Empty);
	}
}

Ejecuta:

dotnet test

🧱 Buenas prácticas

  • Mantén la lógica en la capa Application y el estado persistente (DB) en Infrastructure.
  • Usa DTOs o Records para los datos de entrada/salida (los agregaremos en el siguiente módulo).
  • No dependas de EF Core aún — usa servicios o repositorios abstractos.

✅ Resultado esperado

✔️ API funcional y modular ✔️ Controlador REST limpio ✔️ Lógica separada por capas ✔️ Inyección de dependencias configurada ✔️ Primer test ejecutable


🗄️ Módulo 3 – Persistencia con EF Core 9 y SQLite


🎯 Objetivo

Integrar Entity Framework Core 9 en la capa Infrastructure, crear una base de datos SQLite, y conectar los servicios del dominio con persistencia real.


🧩 Instalación de paquetes

Desde la raíz del proyecto:

cd src/MyApp.Infrastructure
dotnet add package Microsoft.EntityFrameworkCore --version 9.*
dotnet add package Microsoft.EntityFrameworkCore.Sqlite --version 9.*
dotnet add package Microsoft.EntityFrameworkCore.Tools --version 9.*

cd ../MyApp.Api
dotnet add package Microsoft.EntityFrameworkCore.Design --version 9.*

`


🧱 Contexto de datos

MyApp.Infrastructure/Data/AppDbContext.cs

using Microsoft.EntityFrameworkCore;
using MyApp.Domain.Entities;

namespace MyApp.Infrastructure.Data;

public class AppDbContext : DbContext
{
	public DbSet<Product> Products => Set<Product>();

	public AppDbContext(DbContextOptions<AppDbContext> options)
		: base(options) { }

	protected override void OnModelCreating(ModelBuilder modelBuilder)
	{
		modelBuilder.Entity<Product>(entity =>
		{
			entity.HasKey(p => p.Id);
			entity.Property(p => p.Name)
				.IsRequired()
				.HasMaxLength(100);
			entity.Property(p => p.Price)
				.HasPrecision(10, 2);
		});
	}
}

🧠 Configurar EF Core en el API

MyApp.Api/Program.cs

using Microsoft.EntityFrameworkCore;
using MyApp.Infrastructure.Data;
using MyApp.Application.Services;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

// EF Core + SQLite
builder.Services.AddDbContext<AppDbContext>(options =>
	options.UseSqlite(builder.Configuration.GetConnectionString("DefaultConnection")));

// DI Services
builder.Services.AddScoped<IProductService, ProductService>();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
	app.UseSwagger();
	app.UseSwaggerUI();
}

app.MapControllers();
app.Run();

⚙️ Configuración de conexión

MyApp.Api/appsettings.json

{
	"ConnectionStrings": {
		"DefaultConnection": "Data Source=../MyApp.Infrastructure/app.db"
	},
	"Logging": {
		"LogLevel": {
			"Default": "Information",
			"Microsoft": "Warning"
		}
	},
	"AllowedHosts": "*"
}

🧩 Adaptar ProductService a persistencia real

MyApp.Application/Services/ProductService.cs

using MyApp.Domain.Entities;
using MyApp.Infrastructure.Data;
using Microsoft.EntityFrameworkCore;

namespace MyApp.Application.Services;

public class ProductService : IProductService
{
	private readonly AppDbContext _context;

	public ProductService(AppDbContext context)
	{
		_context = context;
	}

	public IEnumerable<Product> GetAll()
	{
		return _context.Products.AsNoTracking().ToList();
	}

	public Product Add(Product product)
	{
		_context.Products.Add(product);
		_context.SaveChanges();
		return product;
	}
}

🔧 Crear y aplicar migraciones

cd src/MyApp.Api
dotnet ef migrations add InitialCreate --project ../MyApp.Infrastructure --startup-project .
dotnet ef database update

💡 EF Core generará automáticamente app.db en MyApp.Infrastructure/.


🧩 Verificar persistencia

Ejecuta el proyecto:

dotnet run --project src/MyApp.Api

Luego prueba:

# Crear productos
http POST https://localhost:5001/api/product name="Monitor" price:=199.99
http POST https://localhost:5001/api/product name="Mouse" price:=35.00

# Listar productos
http GET https://localhost:5001/api/product

Deberías ver la lista persistida en app.db.


🔍 Visualizar base de datos

Puedes inspeccionar la base de datos SQLite con:

  • 🔧 DB Browser for SQLite
  • 🧱 VS Code extension: SQLite Viewer (Ctrl+Shift+P → SQLite: Open Database)

🧾 Buenas prácticas

  • No usar SaveChanges() dentro de bucles. Usa transacciones si modificas múltiples entidades.
  • AsNoTracking() para lecturas rápidas.
  • Migrations en el proyecto de infraestructura, nunca en la API directamente.
  • Context por request (AddDbContext), no singleton.

🧩 Extensión: métodos asíncronos

Actualiza el servicio a versión async:

public async Task<IEnumerable<Product>> GetAllAsync()
	=> await _context.Products.AsNoTracking().ToListAsync();

public async Task<Product> AddAsync(Product product)
{
	_context.Products.Add(product);
	await _context.SaveChangesAsync();
	return product;
}

Y cambia los controladores a async Task<IActionResult>.


✅ Resultado esperado

✔️ Base de datos SQLite real ✔️ Persistencia funcional con EF Core 9 ✔️ Migraciones creadas y aplicadas ✔️ Servicio adaptado a DB ✔️ Lectura y escritura verificadas


🧪 Módulo 4 – Testing integral con xUnit y WebApplicationFactory (.NET 9)

🎯 Objetivo

Probar la API completa con peticiones HTTP simuladas, base de datos en memoria y configuración automática del entorno de test.
Aprenderás a crear un entorno reproducible que valida controladores, servicios y configuración de dependencias.


🧰 Dependencias necesarias

Desde la raíz del proyecto:

cd tests
dotnet new xunit -n MyApp.Tests
cd MyApp.Tests

dotnet add reference ../src/MyApp.Api
dotnet add package Microsoft.AspNetCore.Mvc.Testing --version 9.*
dotnet add package Microsoft.EntityFrameworkCore.InMemory --version 9.*
dotnet add package Microsoft.NET.Test.Sdk --version 17.*
dotnet add package coverlet.collector

`


🧩 Estructura de carpetas recomendada

/tests
	/MyApp.Tests
		/Integration
			ProductApiTests.cs
		/Unit
			ProductServiceTests.cs

🧱 Clase base para tests de integración

tests/MyApp.Tests/Integration/CustomWebApplicationFactory.cs

using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using MyApp.Infrastructure.Data;

namespace MyApp.Tests.Integration;

public class CustomWebApplicationFactory : WebApplicationFactory<Program>
{
	protected override void ConfigureWebHost(IWebHostBuilder builder)
	{
		builder.ConfigureServices(services =>
		{
			// Eliminar configuración de DB real
			var descriptor = services.SingleOrDefault(
				d => d.ServiceType == typeof(DbContextOptions<AppDbContext>));
			if (descriptor != null) services.Remove(descriptor);

			// Añadir base de datos en memoria
			services.AddDbContext<AppDbContext>(options =>
				options.UseInMemoryDatabase("TestDb"));
		});
	}
}

🌐 Test de integración real de la API

tests/MyApp.Tests/Integration/ProductApiTests.cs

using System.Net.Http.Json;
using MyApp.Domain.Entities;
using Xunit;

namespace MyApp.Tests.Integration;

public class ProductApiTests : IClassFixture<CustomWebApplicationFactory>
{
	private readonly HttpClient _client;

	public ProductApiTests(CustomWebApplicationFactory factory)
	{
		_client = factory.CreateClient();
	}

	[Fact]
	public async Task PostProduct_ShouldCreateAndReturnProduct()
	{
		var product = new Product { Name = "Laptop", Price = 999.99M };

		var response = await _client.PostAsJsonAsync("/api/product", product);

		response.EnsureSuccessStatusCode();

		var created = await response.Content.ReadFromJsonAsync<Product>();

		Assert.NotNull(created);
		Assert.Equal("Laptop", created!.Name);
		Assert.True(created.Price > 0);
	}

	[Fact]
	public async Task GetAll_ShouldReturnListOfProducts()
	{
		var response = await _client.GetAsync("/api/product");

		response.EnsureSuccessStatusCode();

		var products = await response.Content.ReadFromJsonAsync<IEnumerable<Product>>();
		Assert.NotNull(products);
	}
}

🧠 Ejecución de los tests

dotnet test --logger "console;verbosity=detailed"

Verás algo como:

[xUnit.net 00:00:01.12] MyApp.Tests.Integration.ProductApiTests.PostProduct_ShouldCreateAndReturnProduct [PASS]
[xUnit.net 00:00:01.19] MyApp.Tests.Integration.ProductApiTests.GetAll_ShouldReturnListOfProducts [PASS]

✅ Si ambos pasan, tu API responde correctamente y la configuración de DI funciona como en producción.


🧩 Test unitario adicional (sin WebApplicationFactory)

tests/MyApp.Tests/Unit/ProductServiceTests.cs

using MyApp.Application.Services;
using MyApp.Domain.Entities;
using Microsoft.EntityFrameworkCore;
using MyApp.Infrastructure.Data;
using Xunit;

public class ProductServiceTests
{
	[Fact]
	public void Add_ShouldStoreInMemoryContext()
	{
		var options = new DbContextOptionsBuilder<AppDbContext>()
			.UseInMemoryDatabase("TestDb2")
			.Options;

		using var context = new AppDbContext(options);
		var service = new ProductService(context);

		var product = new Product { Name = "Mouse", Price = 25 };
		service.Add(product);

		Assert.Single(context.Products);
	}
}

🧾 Consejos de testeo profesional

  • Usa bases de datos in-memory o SQLite in-memory para tests rápidos.
  • Cada test debe ser independiente (recrear el contexto en cada método).
  • Evita mocks innecesarios si puedes testear la integración real.
  • Mantén tests de integración y unitarios separados (carpetas distintas).
  • Puedes añadir dotnet test /p:CollectCoverage=true con coverlet para cobertura.

🧰 Integración en CI/CD

Agrega al workflow de GitHub Actions:

- name: Run tests
  run: dotnet test --no-build --verbosity normal

✅ Resultado esperado

✔️ Tests de integración reales con HTTP ✔️ Base de datos en memoria funcional ✔️ Cobertura de servicios y controladores ✔️ CI con ejecución automática de tests

🖥️ Módulo 5 – Frontend + Integración (Blazor, MAUI y Angular Client)

🎯 Objetivo

Conectar la API .NET creada en módulos previos con diferentes frontends modernos:

  • Blazor WebAssembly para aplicaciones SPA .NET puras
  • .NET MAUI para apps multiplataforma (desktop + móvil)
  • Angular como ejemplo de integración con frameworks externos

🧱 Parte 1: Blazor WebAssembly + API REST

📦 Crear proyecto Blazor

dotnet new blazorwasm -n MyApp.BlazorClient --framework net9.0
cd MyApp.BlazorClient

`

🔗 Configurar HttpClient global

Program.cs

using MyApp.BlazorClient;
using MyApp.BlazorClient.Services;

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");

builder.Services.AddScoped(sp =>
	new HttpClient { BaseAddress = new Uri("https://localhost:5001/") });

builder.Services.AddScoped<ProductApiClient>();

await builder.Build().RunAsync();

💬 Servicio para consumir la API

Services/ProductApiClient.cs

using System.Net.Http.Json;
using MyApp.Shared;

namespace MyApp.BlazorClient.Services;

public class ProductApiClient
{
	private readonly HttpClient _http;

	public ProductApiClient(HttpClient http) => _http = http;

	public async Task<IEnumerable<ProductDto>?> GetAllAsync()
		=> await _http.GetFromJsonAsync<IEnumerable<ProductDto>>("api/product");

	public async Task<ProductDto?> CreateAsync(ProductDto product)
	{
		var response = await _http.PostAsJsonAsync("api/product", product);
		response.EnsureSuccessStatusCode();
		return await response.Content.ReadFromJsonAsync<ProductDto>();
	}
}

🧩 Componente para mostrar productos

Pages/Products.razor

@page "/products"
@inject ProductApiClient Api

<h3>Products</h3>

@if (products == null)
{
	<p>Loading...</p>
}
else
{
	<ul>
		@foreach (var p in products)
		{
			<li>@p.Name - @p.Price €</li>
		}
	</ul>
}

@code {
	IEnumerable<ProductDto>? products;

	protected override async Task OnInitializedAsync()
	{
		products = await Api.GetAllAsync();
	}
}

✅ Ejecuta dotnet run y abre /products → verás los productos cargados desde la API real.


📱 Parte 2: .NET MAUI – App multiplataforma

⚙️ Crear proyecto MAUI

dotnet new maui -n MyApp.Mobile
cd MyApp.Mobile

🔗 Servicio para API

Services/ProductService.cs

using System.Net.Http.Json;
using MyApp.Shared;

namespace MyApp.Mobile.Services;

public class ProductService
{
	private readonly HttpClient _http;

	public ProductService()
	{
		_http = new HttpClient
		{
			BaseAddress = new Uri("https://localhost:5001/")
		};
	}

	public async Task<List<ProductDto>?> GetAllAsync()
		=> await _http.GetFromJsonAsync<List<ProductDto>>("api/product");
}

📲 Página principal

MainPage.xaml.cs

using MyApp.Mobile.Services;

namespace MyApp.Mobile;

public partial class MainPage : ContentPage
{
	private readonly ProductService _service = new();

	public MainPage()
	{
		InitializeComponent();
		LoadProducts();
	}

	private async void LoadProducts()
	{
		var products = await _service.GetAllAsync();
		ProductList.ItemsSource = products;
	}
}

✅ Ejecuta en Android Emulator o Windows → lista real desde API .NET 9.


🌐 Parte 3: Cliente Angular

🧱 Crear cliente Angular

ng new myapp-angular --standalone
cd myapp-angular
npm install axios

🔗 Servicio API

src/app/api.service.ts

import axios from 'axios';

export class ApiService {
	private base = 'https://localhost:5001/api/product';

	async getAll() {
		const res = await axios.get(this.base);
		return res.data;
	}

	async create(product: any) {
		const res = await axios.post(this.base, product);
		return res.data;
	}
}

🧩 Componente simple

src/app/products.component.ts

import { Component, OnInit } from '@angular/core';
import { ApiService } from './api.service';

@Component({
	selector: 'app-products',
	template: `
		<h3>Products</h3>
		<ul>
			<li *ngFor="let p of products">{{p.name}} - {{p.price}}€</li>
		</ul>
	`
})
export class ProductsComponent implements OnInit {
	products: any[] = [];
	api = new ApiService();

	async ngOnInit() {
		this.products = await this.api.getAll();
	}
}

🔐 Autenticación JWT compartida

🛠️ En API (.NET)

builder.Services.AddAuthentication("Bearer")
	.AddJwtBearer(options =>
	{
		options.Authority = "https://localhost:5001";
		options.Audience = "myapi";
	});

🧱 En Blazor / Angular

Adjuntar el token JWT a cada petición:

axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;

🧠 Buenas prácticas de integración

  • Centraliza URLs en un AppSettings o ConfigService.
  • Usa DTOs compartidos entre backend y frontend (MyApp.Shared).
  • En Blazor y MAUI, reutiliza servicios y modelos comunes.
  • Mantén la autenticación y autorización coherente (Identity o JWT).
  • Aísla lógica de red (API Clients) de la UI.

✅ Resultado esperado

✔️ API consumida desde tres clientes reales ✔️ Patrón de comunicación unificado ✔️ Ejemplo funcional Full Stack .NET + Angular ✔️ Base sólida para apps empresariales multiplataforma

⚙️ Módulo 6 – DevOps, CI/CD y despliegue de proyectos .NET (2025)

🎯 Objetivo

Aprender a automatizar el ciclo de vida completo de una aplicación .NET moderna:

  • Build y test automatizados
  • Creación de contenedores Docker
  • Despliegue continuo (CI/CD)
  • Publicación en entornos como Azure Web App, AWS, Render o Vercel

🧱 Estructura base del pipeline

Pipeline de ejemplo con:

  1. GitHub Actions
  2. Docker multi-stage build
  3. Despliegue a Azure Web App

🐋 Parte 1: Dockerfile optimizado

Dockerfile

# Etapa 1: Build
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
WORKDIR /src
COPY . .
RUN dotnet restore
RUN dotnet publish -c Release -o /app/publish

# Etapa 2: Runtime
FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS runtime
WORKDIR /app
COPY --from=build /app/publish .
EXPOSE 8080
ENTRYPOINT ["dotnet", "MyApp.Api.dll"]

`

🧪 Test local

docker build -t myapp-api .
docker run -p 8080:8080 myapp-api

Accede a: http://localhost:8080/swagger


🔄 Parte 2: GitHub Actions – CI/CD

.github/workflows/dotnet-ci.yml

name: .NET CI/CD Pipeline

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup .NET 9
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: '9.0.x'

      - name: Restore dependencies
        run: dotnet restore

      - name: Build
        run: dotnet build --no-restore -c Release

      - name: Run tests
        run: dotnet test --no-build --verbosity normal

      - name: Publish artifacts
        run: dotnet publish -c Release -o out

      - name: Upload build output
        uses: actions/upload-artifact@v4
        with:
          name: published-app
          path: out

✅ Resultado: compila, ejecuta tests y guarda artefactos automáticamente.


☁️ Parte 3: Despliegue automático a Azure Web App

Agrega un segundo workflow:

.github/workflows/deploy.yml

name: Deploy to Azure Web App

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup .NET
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: '9.0.x'

      - name: Publish app
        run: dotnet publish -c Release -o out

      - name: Deploy to Azure
        uses: azure/webapps-deploy@v3
        with:
          app-name: "myapp-dotnet9"
          publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
          package: ./out

🔐 Configurar secretos

En GitHub → Settings > Secrets and variables > Actions

  • AZURE_WEBAPP_PUBLISH_PROFILE = XML del perfil de publicación de Azure

🧩 Parte 4: Docker + GitHub Container Registry (GHCR)

Publicar imagen Docker automáticamente

- name: Log in to GitHub Container Registry
  uses: docker/login-action@v3
  with:
    registry: ghcr.io
    username: ${{ github.actor }}
    password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push Docker image
  uses: docker/build-push-action@v6
  with:
    push: true
    tags: ghcr.io/${{ github.repository_owner }}/myapp:latest

✅ Resultado:


🔧 Parte 5: Variables y configuración por entorno

Usa appsettings.{Environment}.json:

{
	"ConnectionStrings": {
		"DefaultConnection": "Server=db;Database=MyApp;User Id=sa;Password=Pass123;"
	},
	"Logging": {
		"LogLevel": {
			"Default": "Information"
		}
	}
}

En Program.cs:

builder.Configuration.AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", optional: true);

🧠 Buenas prácticas de DevOps

  • Mantén CI/CD separado por entorno (dev, staging, prod).
  • Usa branch protection rules y pull request checks.
  • Monitorea con Application Insights o Grafana + Prometheus.
  • Versiona las imágenes Docker (myapp:v1.0.0).
  • Integra Infrastructure as Code (IaC) con Bicep, Terraform o Pulumi.

🚀 Resultado esperado

✔️ Pipeline CI/CD funcionando en GitHub Actions ✔️ Despliegue automático a Azure Web App ✔️ Imagen Docker publicada en GHCR ✔️ Configuración adaptable por entorno ✔️ Base sólida para flujos DevOps profesionales

🛡️ Módulo 7 – Seguridad, Observabilidad y Rendimiento en .NET 9+

tags:: #dotnet #security #jwt #oauth2 #identity #observability #logging #metrics #performance #tracing


🎯 Objetivo

Asegurar y supervisar una API .NET moderna mediante:

  • Autenticación JWT y OAuth2
  • Protección de endpoints con roles
  • Logging estructurado con Serilog
  • Observabilidad con OpenTelemetry y Grafana
  • Optimización de rendimiento y profiling

🔑 Parte 1: Autenticación JWT

🧩 Instalar paquetes

dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
dotnet add package System.IdentityModel.Tokens.Jwt

`

⚙️ Configurar autenticación en Program.cs

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;

var key = Encoding.ASCII.GetBytes("SuperSecretKeyForJwtToken12345!");

builder.Services.AddAuthentication(options =>
{
	options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
	options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
	options.RequireHttpsMetadata = false;
	options.SaveToken = true;
	options.TokenValidationParameters = new TokenValidationParameters
	{
		ValidateIssuer = false,
		ValidateAudience = false,
		ValidateLifetime = true,
		IssuerSigningKey = new SymmetricSecurityKey(key),
		ValidateIssuerSigningKey = true
	};
});

🧱 Crear controlador de autenticación

Controllers/AuthController.cs

using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{
	[HttpPost("login")]
	public IActionResult Login([FromBody] LoginRequest request)
	{
		if (request.Username != "admin" || request.Password != "1234")
			return Unauthorized();

		var key = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("SuperSecretKeyForJwtToken12345!"));
		var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
		var claims = new[]
		{
			new Claim(ClaimTypes.Name, request.Username),
			new Claim(ClaimTypes.Role, "Admin")
		};

		var token = new JwtSecurityToken(
			claims: claims,
			expires: DateTime.UtcNow.AddHours(1),
			signingCredentials: creds
		);

		return Ok(new { token = new JwtSecurityTokenHandler().WriteToken(token) });
	}
}

public record LoginRequest(string Username, string Password);

🔐 Proteger endpoints

[Authorize(Roles = "Admin")]
[HttpPost]
public IActionResult CreateProduct(Product product)
{
	_service.Add(product);
	return Ok(product);
}

🔑 Parte 2: OAuth2 con Microsoft Identity Platform

Configuración mínima para aplicaciones empresariales.

📦 Paquetes

dotnet add package Microsoft.AspNetCore.Authentication.OpenIdConnect

⚙️ Configuración en Program.cs

builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
	.AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));

🧩 appsettings.json

"AzureAd": {
	"Instance": "https://login.microsoftonline.com/",
	"Domain": "mydomain.onmicrosoft.com",
	"TenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
	"ClientId": "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy",
	"CallbackPath": "/signin-oidc"
}

✅ Ideal para aplicaciones con Azure AD, B2C o entornos corporativos.


📊 Parte 3: Logging estructurado con Serilog

🧱 Instalar

dotnet add package Serilog.AspNetCore
dotnet add package Serilog.Sinks.Console
dotnet add package Serilog.Sinks.File

⚙️ Configurar

Program.cs

using Serilog;

Log.Logger = new LoggerConfiguration()
	.Enrich.FromLogContext()
	.WriteTo.Console()
	.WriteTo.File("logs/log.txt", rollingInterval: RollingInterval.Day)
	.CreateLogger();

builder.Host.UseSerilog();

🧩 Ejemplo en controlador

private readonly ILogger<ProductController> _logger;

public ProductController(IProductService service, ILogger<ProductController> logger)
{
	_service = service;
	_logger = logger;
}

[HttpGet]
public IActionResult GetAll()
{
	_logger.LogInformation("Fetching all products at {time}", DateTime.UtcNow);
	return Ok(_service.GetAll());
}

🔭 Parte 4: Observabilidad con OpenTelemetry

📦 Instalar

dotnet add package OpenTelemetry.Exporter.Console
dotnet add package OpenTelemetry.Exporter.OpenTelemetryProtocol
dotnet add package OpenTelemetry.Extensions.Hosting
dotnet add package OpenTelemetry.Instrumentation.AspNetCore
dotnet add package OpenTelemetry.Instrumentation.Http

⚙️ Configurar

Program.cs

using OpenTelemetry.Trace;
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;

builder.Services.AddOpenTelemetry()
	.WithTracing(t => t
		.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MyApp.Api"))
		.AddAspNetCoreInstrumentation()
		.AddHttpClientInstrumentation()
		.AddOtlpExporter(o => o.Endpoint = new Uri("http://localhost:4317")))
	.WithMetrics(m => m
		.AddAspNetCoreInstrumentation()
		.AddHttpClientInstrumentation()
		.AddRuntimeInstrumentation()
		.AddOtlpExporter());

📈 Exportar datos a Grafana o Jaeger

Ejecuta contenedores con Docker:

docker run -d --name jaeger -e COLLECTOR_ZIPKIN_HTTP_PORT=9411 -p 16686:16686 jaegertracing/all-in-one:latest

Accede a: http://localhost:16686 → visualiza trazas y spans.


⚡ Parte 5: Optimización de rendimiento

🧩 Diagnóstico en tiempo real

dotnet-counters monitor --process-id <PID>

🧰 Perf tips:

  • Usa async/await en IO intensivo
  • Implementa caching con IMemoryCache o Redis
  • Evita ToList() prematuros en LINQ
  • Usa AddResponseCompression() y UseResponseCaching()
  • Ajusta Kestrel para concurrencia alta:
builder.WebHost.ConfigureKestrel(options =>
{
	options.Limits.MaxConcurrentConnections = 1000;
});

🧠 Buenas prácticas

  • Mantén claves fuera del código → usa dotnet user-secrets o Azure Key Vault.
  • Registra solo lo necesario → usa niveles (Information, Warning, Error).
  • Aplica Rate Limiting en endpoints públicos (AddRateLimiter).
  • Combina Serilog + OpenTelemetry para trazas unificadas.
  • Revisa Memory Dumps con dotnet-dump analyze en producción.

✅ Resultado esperado

✔️ Autenticación JWT / OAuth2 funcionando ✔️ Endpoints protegidos con roles ✔️ Logging estructurado y persistente ✔️ Trazabilidad distribuida con OpenTelemetry ✔️ Monitoreo de rendimiento en tiempo real ✔️ API lista para entornos productivos y auditables

🏗️ Módulo 8 – Arquitecturas avanzadas y patrones distribuidos (.NET 9+)

Objetivo práctico

Implementar patrones reales para sistemas distribuidos con .NET 9: Microservicios, CQRS, Event Sourcing, Sagas/Compensations, EventBus (RabbitMQ), gRPC, Outbox pattern, y resiliencia (Polly). Cada bloque incluye ejemplos ejecutables mínimos y comandos para probar localmente.


1. Diseño general de microservicios

  • Servicios pequeños con responsabilidad única (User, Order, Payment, Catalog).
  • Comunicación:
    • Sincrónica: gRPC o HTTP/REST.
    • Asincrónica: RabbitMQ / Kafka / Dapr pub/sub.
  • Persistencia: base de datos por servicio (DB-per-service).
  • Consistencia eventual: Outbox + EventBus o Sagas para flujos transaccionales.

2. CQRS con MediatR (comandos/consultas separados)

2.1 Ejemplo: comando y handler con MediatR

Código: Command y Handler

// Application/Commands/CreateOrderCommand.cs
public record CreateOrderCommand(Guid CustomerId, List<OrderItemDto> Items) : IRequest<Guid>;

// Application/Handlers/CreateOrderHandler.cs
public class CreateOrderHandler : IRequestHandler<CreateOrderCommand, Guid>
{
	private readonly AppDbContext _db;
	private readonly IPublishEndpoint _publisher; // MassTransit or custom bus

	public CreateOrderHandler(AppDbContext db, IPublishEndpoint publisher)
	{
		_db = db;
		_publisher = publisher;
	}

	public async Task<Guid> Handle(CreateOrderCommand request, CancellationToken ct)
	{
		var order = new Order { CustomerId = request.CustomerId, Items = request.Items.Select(i => new OrderItem(i.ProductId, i.Quantity)).ToList() };
		_db.Orders.Add(order);
		await _db.SaveChangesAsync(ct);

		// Publicar evento de dominio
		await _publisher.Publish(new OrderCreatedEvent(order.Id, order.Total), ct);

		return order.Id;
	}
}

`

2.2 Registro en DI

// Program.cs
builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblyContaining<CreateOrderCommand>());

3. Event Sourcing (concepto + ejemplo mínimo)

  • Almacenar sólo eventos inmutables; reconstruir estado por rehidratación.
  • Usar una tabla Events con Id, AggregateId, Type, Data(json), Version, CreatedAt.

3.1 Ejemplo: evento y apéndice

Código: Event entity y append

// Infrastructure/Events/EventEntity.cs
public class EventEntity
{
	public Guid Id { get; set; } = Guid.NewGuid();
	public Guid AggregateId { get; set; }
	public string Type { get; set; } = null!;
	public string Data { get; set; } = null!;
	public int Version { get; set; }
	public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
}

// Usage: append event
var evt = new EventEntity { AggregateId = order.Id, Type = "OrderCreated", Data = JsonSerializer.Serialize(new { order.Id, order.Total }), Version = 1 };
db.Events.Add(evt);
await db.SaveChangesAsync();

4. Outbox pattern (garantizar publicación de eventos)

  • Escribir evento en la misma transacción que la entidad (DB), luego enviar los eventos desde la tabla Outbox mediante un proceso background para asegurar entrega at-least-once.

4.1 Ejemplo: esquema Outbox y worker

Código: Outbox entity

public class OutboxMessage
{
	public Guid Id { get; set; } = Guid.NewGuid();
	public string Type { get; set; } = null!;
	public string Payload { get; set; } = null!;
	public DateTime OccurredAt { get; set; } = DateTime.UtcNow;
	public bool Sent { get; set; } = false;
}

Código: Worker simple (BackgroundService)

public class OutboxDispatcher : BackgroundService
{
	private readonly IServiceScopeFactory _scopes;
	private readonly IPublishEndpoint _publisher;

	public OutboxDispatcher(IServiceScopeFactory scopes, IPublishEndpoint publisher)
	{
		_scopes = scopes;
		_publisher = publisher;
	}

	protected override async Task ExecuteAsync(CancellationToken stoppingToken)
	{
		while (!stoppingToken.IsCancellationRequested)
		{
			using var scope = _scopes.CreateScope();
			var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
			var pending = await db.Set<OutboxMessage>().Where(m => !m.Sent).Take(20).ToListAsync(stoppingToken);

			foreach (var msg in pending)
			{
				await _publisher.Publish(msg, stoppingToken); // map to domain event
				msg.Sent = true;
			}

			await db.SaveChangesAsync(stoppingToken);
			await Task.Delay(1000, stoppingToken);
		}
	}
}

5. EventBus con RabbitMQ (MassTransit ejemplo)

5.1 Docker Compose para RabbitMQ

Código: docker-compose.yml

version: '3.8'
services:
  rabbitmq:
    image: rabbitmq:3.11-management
    ports:
      - "5672:5672"
      - "15672:15672"

Comando:

docker compose up -d

5.2 Configurar MassTransit en servicios

Código: Program.cs (MassTransit)

builder.Services.AddMassTransit(x =>
{
	x.UsingRabbitMq((context, cfg) =>
	{
		cfg.Host("rabbitmq", "/", h => { /* credenciales si es necesario */ });
		cfg.ConfigureEndpoints(context);
	});
});

5.3 Consumidor simple

Código: OrderCreatedConsumer

public class OrderCreatedEvent
{
	public Guid OrderId { get; init; }
	public decimal Total { get; init; }
}

public class OrderCreatedConsumer : IConsumer<OrderCreatedEvent>
{
	public Task Consume(ConsumeContext<OrderCreatedEvent> context)
	{
		Console.WriteLine($"OrderReceived: {context.Message.OrderId} total {context.Message.Total}");
		return Task.CompletedTask;
	}
}

6. Sagas (orquestación de procesos) con MassTransit

  • Usar Sagas para orquestar flujos (Order -> Payment -> Inventory -> Confirmation).
  • Persistir estado de saga (EF Core or Mongo) y modelar correcciones (compensaciones).

6.1 Ejemplo: Saga State & Saga

Código: OrderState

public class OrderState : SagaStateMachineInstance
{
	public Guid CorrelationId { get; set; }
	public string CurrentState { get; set; } = null!;
	public Guid OrderId { get; set; }
	public bool PaymentConfirmed { get; set; }
}

Código: StateMachine (esqueleto)

public class OrderStateMachine : MassTransitStateMachine<OrderState>
{
	public State AwaitingPayment { get; private set; }

	public Event<OrderCreatedEvent> OrderCreated { get; private set; }

	public OrderStateMachine()
	{
		InstanceState(x => x.CurrentState);

		Event(() => OrderCreated, x => x.CorrelateById(m => m.Message.OrderId));

		Initially(
			When(OrderCreated)
				.Then(context => { context.Instance.OrderId = context.Data.OrderId; })
				.TransitionTo(AwaitingPayment)
		);

		// agregar manejo de pago, compensaciones, timeouts...
	}
}

7. gRPC para llamadas síncronas rápidas

7.1 Definir contrato .proto

Código: proto/order.proto

syntax = "proto3";
package orders;

service OrderService {
	rpc GetOrder (OrderRequest) returns (OrderReply);
}

message OrderRequest {
	string id = 1;
}

message OrderReply {
	string id = 1;
	double total = 2;
	string status = 3;
}

7.2 Agregar gRPC al proyecto (.NET)

// Program.cs
builder.Services.AddGrpc();
app.MapGrpcService<OrderGrpcService>();

7.3 Implementar servicio gRPC

Código: OrderGrpcService.cs

public class OrderGrpcService : OrderService.OrderServiceBase
{
	public override Task<OrderReply> GetOrder(OrderRequest request, ServerCallContext context)
	{
		// obtener desde DB
		return Task.FromResult(new OrderReply { Id = request.Id, Total = 100.0, Status = "Created" });
	}
}

8. Dapr (alternativa ligera para pub/sub, state, bindings)

  • Dapr simplifica pub/sub, state stores y service invocation sin acoplar demasiado.
  • Instalar Dapr CLI local y ejecutar dapr run --app-id orders -- dotnet run.

8.1 Ejemplo: publicar evento con Dapr

Código: Publicar evento (HTTP)

var client = new HttpClient();
await client.PostAsJsonAsync("http://localhost:3500/v1.0/publish/pubsub/order_created", new { orderId = id, total = total });

8.2 Suscriptor en otro servicio

  • Configurar endpoint /dapr/subscribe o usar SDK .NET (Dapr.Client).

9. Resiliencia: Polly (reintentos, circuit breaker, timeout)

9.1 Paquete y política

dotnet add package Polly.Extensions.Http

9.2 Ejemplo: HttpClient con políticas

Código: Program.cs - HttpClientFactory + Polly

builder.Services.AddHttpClient("payment", client => client.BaseAddress = new Uri("https://payment.local"))
	.AddTransientHttpErrorPolicy(p => p.WaitAndRetryAsync(3, _ => TimeSpan.FromMilliseconds(500)))
	.AddTransientHttpErrorPolicy(p => p.CircuitBreakerAsync(5, TimeSpan.FromSeconds(30)));

10. Testing de integración distribuida (Testcontainers)

10.1 Usar Testcontainers.NET para RabbitMQ/DB

Código: ejemplo de test setup (C#)

var rabbit = new RabbitMqTestcontainerBuilder().Build();
await rabbit.StartAsync();
// iniciar bus con conexión rabbit.ConnectionString

11. Observabilidad específica de microservicios

  • Trazas: OpenTelemetry + Jaeger (OTLP).
  • Métricas: Prometheus exporters + Grafana dashboards por servicio.
  • Logs: Correlación por traceId en Serilog/Seq.

12. Despliegue y orquestación recomendada

  • Kubernetes con Helm charts.
  • Separar infra: RabbitMQ (stateful), DB (managed), app (deployments).
  • Rolling updates + readiness/liveness probes.
  • Considerar Service Mesh (Istio/Linkerd) para políticas de red y telemetría.

13. Checklist práctico (qué implementar primero)

  • Separar responsabilidades en servicios pequeños.
  • Implementar CQRS mínimo (commands + queries).
  • Añadir Outbox para eventos publicados desde la transacción DB.
  • Desplegar RabbitMQ local y validar pub/sub.
  • Implementar Sagas para flujos de negocio multistep.
  • Añadir gRPC para caminos síncronos de baja latencia.
  • Integrar resiliencia con Polly.
  • Habilitar OpenTelemetry y dashboards básicos.
  • Tests de integración end-to-end con Testcontainers.

Comandos útiles rápidos

# levantar RabbitMQ
docker compose -f docker-compose.yml up -d

# ejecutar migraciones (ej. infra project)
dotnet ef database update --project src/MyService.Infrastructure --startup-project src/MyService.Api

# ejecutar tests con containers
dotnet test tests/MyService.Tests

Notas de implementación

  • Empezar simple: CQRS + Outbox + EventBus. Añadir Sagas cuando necesites coordinaciones transaccionales.
  • Priorizad idempotencia en consumidores (recibidos múltiples).
  • Modelar eventos como contratos estables (versionable).
  • Monitorizar entrega (DLQ, retries y dead-letter queues en RabbitMQ).

🚀 Módulo 9 – Rendimiento, Profiling y Publicación Cloud-Ready (.NET 9+)

Objetivo práctico

Optimizar, analizar y desplegar aplicaciones .NET 9 en entornos cloud-ready, midiendo rendimiento con herramientas reales, aplicando patrones de optimización, y preparando el proyecto para Azure, AWS, o Kubernetes con CI/CD y observabilidad.


1. Fundamentos de rendimiento en .NET

Principios clave

  • Evitar bloqueos innecesarios → usar async/await en IO-bound.
  • Reducir asignaciones en bucles críticos (usar Span<T>, Memory<T>).
  • Evitar LINQ costoso en loops → preferir bucles explícitos o ArrayPool<T>.
  • Configurar correctamente el Garbage Collector (GC):
    • Server GC para entornos productivos.
    • Sustituir colecciones por versiones especializadas (ConcurrentQueue, ArrayPool).

Configuración del GC

<!-- app.config o runtimeconfig.json -->
<configuration>
	<runtime>
		<gcServer enabled="true"/>
		<gcConcurrent enabled="true"/>
	</runtime>
</configuration>

`


2. Profiling y diagnóstico local

Herramientas recomendadas

  • dotnet-counters → métricas en tiempo real.
  • dotnet-trace → capturar eventos de rendimiento.
  • dotnet-dump → análisis de memoria.
  • PerfView o Visual Studio Profiler → profiling detallado.
  • JetBrains dotTrace / dotMemory → análisis avanzado.

Ejemplo: métricas en tiempo real

dotnet-counters monitor --process-id <pid> System.Runtime

Ejemplo: grabar un trace

dotnet-trace collect --process-id <pid> --format speedscope

Abre en https://www.speedscope.app para visualizar la llama de CPU.


3. Benchmarking con BenchmarkDotNet

Instalación

dotnet add package BenchmarkDotNet

Ejemplo: benchmark simple

using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;

public class StringBenchmarks
{
	private string[] words = Enumerable.Repeat("benchmark", 1000).ToArray();

	[Benchmark]
	public string Join() => string.Join(",", words);

	[Benchmark]
	public string ManualConcat()
	{
		var sb = new StringBuilder();
		foreach (var w in words) sb.Append(w).Append(',');
		return sb.ToString();
	}
}

BenchmarkRunner.Run<StringBenchmarks>();

Salida típica:

|     Method |      Mean |    Error |   StdDev | Allocated |
|------------ |----------:|---------:|---------:|-----------:|
|        Join |  12.45 us | 0.11 us  | 0.10 us  |   12.3 KB  |
| ManualConcat|  25.18 us | 0.15 us  | 0.14 us  |   48.5 KB  |

4. Diagnóstico en producción con OpenTelemetry + Logs

Instrumentación básica

builder.Services.AddOpenTelemetry()
	.WithMetrics(m => m.AddAspNetCoreInstrumentation().AddRuntimeInstrumentation())
	.WithTracing(t => t.AddAspNetCoreInstrumentation().AddHttpClientInstrumentation());

Exportar a herramientas

  • Azure Monitor, Grafana, Jaeger o Zipkin.
  • Log sinks: Serilog + Seq o Application Insights.

Ejemplo: configuración Serilog + Seq

Log.Logger = new LoggerConfiguration()
	.WriteTo.Seq("http://localhost:5341")
	.Enrich.WithCorrelationId()
	.CreateLogger();

5. Optimización de API ASP.NET Core

5.1 Configuración recomendada en Program.cs

builder.WebHost
	.UseKestrel(o =>
	{
		o.AddServerHeader = false;
		o.Limits.MaxConcurrentConnections = 1000;
		o.Limits.KeepAliveTimeout = TimeSpan.FromSeconds(120);
	})
	.UseUrls("http://*:5000");

builder.Services.Configure<RouteOptions>(o => o.LowercaseUrls = true);
builder.Services.AddResponseCompression();
builder.Services.AddMemoryCache();

5.2 Minimizar overhead de middleware

  • Evitar middlewares innecesarios en rutas críticas.
  • Aplicar [ResponseCache] o ETag en endpoints idempotentes.
  • Usar IResult minimal APIs para máxima eficiencia.

5.3 Ejemplo de endpoint optimizado

app.MapGet("/status", () => Results.Ok(new { uptime = Environment.TickCount64 }))
	.CacheOutput(policy => policy.Expire(TimeSpan.FromSeconds(30)));

6. Load Testing (carga y stress)

Opciones

  • k6 → moderno, scriptable (JavaScript).
  • Bombardier → CLI sencilla.
  • Azure Load Testing → pruebas cloud integradas.

Ejemplo con k6

npm install -g k6
// load.js
import http from 'k6/http';
import { sleep } from 'k6';

export default function () {
	http.get('http://localhost:5000/api/orders');
	sleep(0.1);
}

Ejecutar:

k6 run --vus 50 --duration 30s load.js

7. Contenedores y publicación

Dockerfile productivo optimizado

FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS base
WORKDIR /app
EXPOSE 8080

FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
WORKDIR /src
COPY . .
RUN dotnet publish -c Release -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /app
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "MyApp.dll"]

Ejecutar y probar

docker build -t myapp:latest .
docker run -p 8080:8080 myapp:latest

8. Despliegue en Azure

Opción 1: Azure App Service

az webapp up --name myapp2025 --resource-group MyRG --runtime "DOTNET:9"

Opción 2: Azure Container Apps (ACA)

az containerapp up \
	--name myapp \
	--resource-group MyRG \
	--environment myenv \
	--image myapp:latest \
	--ingress external --target-port 8080

Opción 3: Azure Kubernetes Service (AKS)

kubectl create namespace myapp
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml

9. Despliegue en AWS

Opción 1: AWS Elastic Beanstalk

eb init -p "dotnet 9" MyApp
eb create myapp-env

Opción 2: AWS ECS con Fargate

aws ecs create-cluster --cluster-name MyCluster
aws ecs register-task-definition --cli-input-json file://ecs-task.json
aws ecs create-service --cluster MyCluster --service-name myapp --task-definition myapp-task

Opción 3: AWS Lambda con .NET

dotnet lambda deploy-serverless MyLambdaApp

10. CI/CD cloud-ready (GitHub Actions ejemplo)

Workflow .github/workflows/build-deploy.yml

name: Build and Deploy

on:
  push:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Setup .NET
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: '9.0.x'
      - name: Build
        run: dotnet build --configuration Release
      - name: Publish
        run: dotnet publish -c Release -o output
      - name: Deploy to Azure
        uses: azure/webapps-deploy@v3
        with:
          app-name: myapp2025
          publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
          package: output

11. Monitorización post-despliegue

Azure Application Insights

  • Trazas automáticas de peticiones, dependencias y excepciones.
  • Consultas Kusto (KQL) para análisis:
requests
| where duration > 200ms
| summarize avg(duration) by operation_Name

AWS CloudWatch

  • Logs centralizados, alarmas en latencia o errores.
  • Integración con AWS X-Ray para tracing distribuido.

12. Checklist de optimización y despliegue

  • Analizar rendimiento con dotnet-trace y BenchmarkDotNet.
  • Minimizar allocations y latencia de endpoints.
  • Agregar caching (en memoria o Redis).
  • Configurar logging estructurado + correlación.
  • Dockerizar con imagen ligera (aspnet:9.0-alpine).
  • Añadir health checks (/healthz).
  • Integrar OpenTelemetry y Application Insights.
  • Desplegar en Azure/AWS con CI/CD automatizado.
  • Ejecutar test de carga post-despliegue.
  • Revisar trazas y métricas para mejorar el siguiente ciclo.

13. Ejemplo: pipeline local → cloud (resumen)

# Build + test
dotnet build -c Release
dotnet test

# Containerize
docker build -t myapp:latest .

# Run local with telemetry enabled
docker run -p 8080:8080 -e OTEL_EXPORTER_OTLP_ENDPOINT=http://jaeger:4317 myapp

# Deploy to Azure
az containerapp up --name myapp --resource-group MyRG --image myapp:latest

14. Siguientes pasos

  • Aplicar observabilidad avanzada con OpenTelemetry Collector + Grafana
  • Integrar CD con ArgoCD o GitHub Actions + Bicep.
  • Añadir performance budgets en CI (medir tiempos de endpoints).
  • Monitorear SLA y costos en tiempo real.

Módulo 1 – Setup + entorno productivo moderno (.NET 9) Módulo 2 – API REST limpia con ASP.NET Core Módulo 3 – Persistencia con EF Core Módulo 4 – Testing con xUnit Módulo 5 – Frontend y Blazor/MAUI Módulo 6 – CI/CD y Dockerización Módulo 7 – Casos avanzados CQRS + EventBus + Auth Módulo 8 – Arquitecturas distribuidas y resiliencia