Saltar al contenido

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript... y lo que venga ;)

18 años online

el blog de José M. Aguilar

Inicio El autor Contactar

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web
ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript...

¡Microsoft MVP!
martes, 4 de febrero de 2025
Máquina compleja con piezas explotando

Como sabemos, es muy sencillo implementar servicios en segundo plano alojados en el interior de aplicaciones ASP.NET Core porque el framework nos proporciona infraestructura que simplifica la tarea, permitiendo que nos enfoquemos en la lógica de negocio que queremos ejecutar en background en lugar de tener que preocuparnos de los aspectos de más bajo nivel necesarios para hacer que funcione.

En la práctica, basta con heredar de la clase BackgroundService y sobreescribir el método ExecuteAsync para implementar la lógica que queremos ejecutar en segundo plano. Por ejemplo, el siguiente servicio se encarga de escribir un mensaje en la consola cada segundo:

public class MyBackgroundService : BackgroundService
{
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
	    Console.WriteLine($"Current time: {DateTime.Now:T}");
	    await Task.Delay(1000, stoppingToken);
        }
    }
}

Luego tendríamos registrar este servicio en el contenedor de dependencias de ASP.NET Core, de forma que el framework lo detectará automáticamente y lo lanzará cuando la aplicación sea iniciada:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHostedService<MyBackgroundService>();
...

Al ejecutar, veremos que, en la consola donde hemos lanzado la aplicación, se escribirá periódicamente la hora desde la tarea en segundo plano:

Current time: 13:34:06
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: https://localhost:7080
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://localhost:5148
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: D:\Projects\BackgroundServiceCrash
Current time: 13:34:07
Current time: 13:34:08

Pero bueno, no es esto de lo que quería hablar, sino de lo que ocurre cuando en uno de estos servicios en segundo plano se produce un error... porque ojo, que si no tenemos cuidado puede tumbar completamente nuestra aplicación.

lunes, 3 de febrero de 2025
Desarrollador construyendo una casa con Lego

Estrenamos febrero con la recopilación número 595 de enlaces interesantes, cargado de contenidos variados y de calidad relacionado con el desarrollo de software: .NET, ASP.NET, Azure, conceptos, patrones y buenas prácticas, IA, programación web (HTML, CSS, Javascript, frameworks), Visual Studio y herramientas, .NET MAUI, y otros.

Sin duda, la sorpresa y gran protagonista de la semana ha sido el lanzamiento de DeepSeek R1, la IA open source que ha puesto patas arriba a los que hasta ahora se consideraban los reyes del mambo, demostrando que China compite en primera división de los modelos generativos.

También es interesante echar un vistazo bajo el capó de los navegadores, a los mecanismos encargados de interpretar los para interpretar el código HTML y CSS que les llega y crear su representación visual. Aditya Bhattacharya nos lo cuenta el artículo HTML & CSS Deep Dive Part 1: How Browsers Make Sense of Your Code.

Sergey Teplyakov nos recuerda en el post The Dangers of Async Void lo peligroso que puede ser crear métodos o funciones async void en C#, una práctica que puede llegar a tumbar por completo una aplicación.

El amigo Braulio Díez vuelve con sus historias para no dormir, con el artículo Las migraciones tienen veneno, una visión práctica y realista de lo que hay detrás de estos proyectos que, aunque a primera vista pueden parecer sencillos, tienen bastantes trampas ocultas.

Por último, desde CampusMVP nos llega un post que abre los ojos sobre la realidad del open source: ¿es gratis? ¿quién lo mantiene? ¿quién contribuye? ¿Es sostenible? Muchas preguntas interesantes a las que podremos dar respuesta en el post y vídeo donde José Manuel Alarcón y Jorge Turrado debaten sobre el tema.

El resto de enlaces, a continuación 🙂

Por si te lo perdiste...

.NET Core / .NET

martes, 28 de enero de 2025
Un brazo robótico llamado NuGet gestionando paquetes en un almacén

Habitualmente los paquetes NuGet que usamos en un proyecto se registran en entradas <PackageReference> de su archivo .csproj. Es un mecanismo sencillo y efectivo cuando trabajamos con un único proyecto o un número reducido de ellos.

Sin embargo, cuando la cosa crece y estamos trabajando con muchos proyectos que usan paquetes comunes cuyas versiones deben estar alineadas, todo se complica un poco, y trabajar con ellos se puede convertir en algo bastante tedioso. Y más aún si no usamos una herramienta visual como NuGet Package Manager de Visual Studio.

Para estos escenarios, NuGet 6.2, lanzado en agosto de 2023 y presente por defecto en todas las instalaciones actualizadas de .NET y Visual Studio, introdujo el concepto de gestión centralizada de paquetes (en inglés, Central Package Management o CPM). Esta funcionalidad nos brinda la posibilidad de definir en un archivo independiente los paquetes utilizados, con sus versiones correspondientes, de forma que todos los proyectos de la solución puedan hacer referencia a él y mantener sus dependencias actualizadas.

lunes, 27 de enero de 2025
Enlaces interesantes

Aquí tenemos la entrega número 594 de enlaces a contenidos interesantes que he ido recopilando durante la semana, con mucho .NET, ASP.NET Core, IA, Azure, JavaScript, CSS, herramientas de desarrollo y más.

En esta ocasión me gustaría destacar el post de Neo Kim sobre cómo funciona Bluesky. Me encantan estos posts que detallan los engranajes que hay por detrás de aplicaciones que todos conocemos y que tienen unos requisitos altísimos de escalabilidad y rendimiento.

También me ha resultado muy interesante el post de Milan Jovanović sobre cómo escalar monolitos, porque creo que puede ser de utilidad si tenéis aplicaciones que con el tiempo han ido creciendo más allá de lo que se esperaba en un principio.

También en la sección "cómo funcionan las cosas que usamos todos los días" 😉, el post de Moncef Abboud es muy interesante para profundizar un poco en los algoritmos de compresión más habituales.

Por último, me ha hecho ilusión ver que NDepend sigue evolucionando e introduciendo mejoras para ofrecer perspectivas únicas de nuestras bases de código. Vale la pena echarle un vistazo.

Y ahora, a por el resto...

Por si te lo perdiste...

.NET Core / .NET

martes, 21 de enero de 2025
Programadores intentando entender un código imposible

En general, el uso de expresiones largas debería estar prohibido por ley. Hay pocas cosas que ataquen tanto a la legibilidad de un código como una expresión larga y compleja a la que tengamos que dedicar un buen rato cada vez que intentemos comprenderla. Y no digamos si nos toca modificarla 😱

Aunque esto es aplicable a cualquier tipo de expresión, en este post me voy a centrar en los predicados, que al fin y al cabo representan las condiciones que determinan el comportamiento de una aplicación.

Veamos un ejemplo de if con un predicado que implementa una condición de negocio necesaria para que un usuario user pueda realizar una tarea concreta en la cuenta account:

if (account is not null && account.IsActive && account.HasSubscription 
    && account.SubscriptionStartDate <= DateTime.Today && account.SubscriptionEndDate 
    >= DateTime.Now.AddDays(1) && (account.SubscriptionLevel == "Standard" || 
    account.SubscriptionLevel == "Premium") && user.IsActive && (user.HasRole("admin") 
    || (user.HasRole("owner"))) && user.AccountId == account.Id)
{
    account.ChangePaymentMethod("paypal");
}

Es un poco difícil de leer, ¿verdad? 😅 Bueno, está algo forzado para ilustrar bien el ejemplo, pero seguro que en nuestras bases de código podríamos reconocer fragmentos conceptualmente similares.

Básicamente, la condición anterior verifica si el estado de la cuenta account es válido para realizar la tarea, comprobando que sea correcta, esté activa, y tenga en vigor una suscripción de nivel "Standard" o "Premium", así como que el usuario user tenga permisos para hacerlo, comprobando que esté activo, tenga un rol de "admin" u "owner", y pertenezca a la cuenta account.

Obviamente, no podemos evitar que la lógica de negocio sea compleja, eso no depende de nosotros. Pero sí podemos hacer que la forma de expresarla mediante código sea más sencilla y legible, así que, ¡manos a la obra!

lunes, 20 de enero de 2025
Pitonisa viendo el futuro de JavaScript

Aquí está la recopilación semanal número 593 de enlaces interesantes, donde podéis encontrar un montón de referencias a artículos sobre C#, .NET, ASP.NET, Azure, desarrollo web, inteligencia artificial, Visual Studio y otros temas 🙂

Destacable el post "Tendencias en programación JavaScript para 2025", de José Manuel Alarcón, donde desvela hacia dónde se dirige el desarrollo JavaScript este año recién estrenado, en términos de herramientas, frameworks, metaframeworks, programación en backend y los nuevos paradigmas impulsados por la irrupción de la inteligencia artificial. Si usáis este lenguaje y su ecosistema, no os lo perdáis.

Los que diseñáis sistemas distribuidos con ASP.NET Core, os puede venir bien echar un vistazo a la introducción de Ricardo Peres a la implementación de trazas distribuidas en ASP.NET Core.

El artículo de Mark Heath sobre el uso de tools de forma segura con LLMs, Using Tools (Safely) with LLMs, me ha sido útil para descubrir que las bibliotecas cliente de Azure OpenAI también tienen la capacidad de ejecutar herramientas, algo que pensaba que había que hacer manualmente o con frameworks más potentes como Semantic Kernel.

Y muy bueno el recopilatorio del equipo de Visual Studio sobre novedades destacables que se introdujeron en el producto durante 2024. Si usáis a diario esta herramienta, echadle un ojo porque hay cosas muy interesantes.

Espero que os sean de utilidad 🙂

Por si te lo perdiste...

.NET Core / .NET

martes, 14 de enero de 2025
Enlaces interesantes

Tras el parón navideño, volvemos a la carga con la primera recopilación de 2025 🙂

Bueno, la frase anterior no es del todo cierta. Por una parte, aunque haya dejado de publicar durante un par de semanas, no he dejado de recopilar enlaces, así que esta edición es especialmente extensa: más de 90 enlaces. Y por otra parte, en realidad sería la segunda recopilación, si contamos la revisión de los contenidos más vistos del blog durante el pasado año que publiqué ayer 😊

Pero bueno, al tema...

Es difícil destacar algo en concreto ante tanto contenido, pero quizás me quedo con el post "The Myth of Perfect Code: Why It’s Hurting You More Than Helping", donde Terrance Craddock reflexiona sobre lo que deberíamos considerar "código perfecto".

También me voy a quedar con algo que, por diferente, me ha llamado la atención: "Unique Solving Method for Rubik's Cube", un método para resolver el cubo de Rubik presentado de forma muy visual. Si sois de los que en los 80 pasasteis horas intentando resolverlo, seguro que como mínimo os resultará curioso 🙂

Por si te lo perdiste...

.NET Core / .NET

lunes, 13 de enero de 2025
Top Posts 2024 en Variable Not Found

Pues sí, se acabaron las fiestas y aquí estamos de nuevo, volviendo a la rutina. Con el 2025 recién estrenado, ante todo, me gustaría aprovechar la ocasión para desearos que sea un gran año en todos los sentidos🙂

Y para empezar con buen pie, vamos a seguir la tradición de aprovechar este primer post para hacer un breve recopilatorio de los artículos más leídos el año anterior, con idea de que podáis descubrir contenidos que quizás os habíais perdido, reencontraros con algo que os interesó en su momento, o simplemente ver qué contenidos están llamando más la atención al resto de lectores del blog.

Top 10 posts 2024 en Variable Not Found

En décimo lugar, inaugurando el top ten de 2024 tenemos una llamada de atención: el artículo "¡No uses ContainsKey() en un diccionario .NET para ver si existe un elemento antes de obtenerlo!" muestra el impacto en el rendimiento de la doble búsqueda (una para ver si existe el elemento y otra para obtenerlo) y cómo podemos solucionarlo fácilmente con las herramientas que proporciona el propio framework.

Seguidamente, en el noveno puesto de la lista, respondemos a una pregunta bastante habitual cuando empezamos con ASP.NET Core: ¿por qué mi aplicación no arranca? En el artículo "No se puede conectar al servidor web 'https', el servidor web ya no funciona y otras pistas de que no has lanzado correctamente tu aplicación ASP.NET Core", además de la respuesta, veremos otros síntomas que nos pueden ayudar a identificar el problema. Spoiler: has olvidado incluir el app.Run() al final del código de inicialización 😉