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, 29 de octubre de 2024
Piezas de un puzzle sugiriendo que todo va encajando en .NET

Seguimos analizando las novedades de .NET 9, y en esta ocasión le toca el turno a la actualización en miembros de clases parciales de C# 13.

Las clases o tipos parciales de C# están con nosotros casi desde los inicios de .NET, desde los tiempos de C# 2.0. Como sabemos, éstas permiten dividir la implementación de un tipo en varios archivos. Su existencia se debía a varios motivos:

  • Permitir a los desarrolladores trabajar en clases de forma concurrente sin bloquearse (recordemos que por aquellos tiempos aún pululaban por ahí infames sistemas de control de código fuente como SourceSafe).
  • Trocear clases extensas para facilitar su comprensión y mantenimiento.
  • Y, el que es más importante, posibilitar el uso sencillo de herramientas de generación de código que, de alguna forma, tuvieran que completar la implementación de código del usuario.

Acompañando a las clases parciales, se introdujo también el soporte para métodos parciales. Aunque su uso era limitado y podía depararnos algunas sorpresas, eran útiles para comunicar de forma segura distintos fragmentos de la clase. Básicamente, consistía en que una porción de una clase podía definir un método e invocarlo desde su código, delegando a otras porciones su implementación. Si no se implementaba en ninguna otra parte, simplemente no se generaba el código de la invocación.

Veamos un ejemplo del uso de estas características:

// Archivo: Ejemplo.Main.cs
public partial class Ejemplo
{    
    // El método parcial se declara sin implementación...
    partial void Log(string msg);

    public void RealizarAlgo()
    {
        hacerAlgoComplejo();
        Log("¡Ojo!"); // Usamos el método
                    // parcial declarado antes
    }
}

// Archivo: Ejemplo.Log.cs
public partial class Ejemplo
{
    partial void Log(string msg)
    {
        Console.WriteLine(msg);
    }
}

Pues bien, casi dos décadas más tarde, los tipos parciales van a recibir algunas actualizaciones interesantes en C# 13, posibilitando que, además de métodos, puedan definirse propiedades parciales.

lunes, 28 de octubre de 2024
Enlaces interesantes

Aquí tenéis los enlaces recopilados durante la semana. 

En esta ocasión, creo que como mínimo vale la pena echar un vistazo a lo nuevo de Anthropic, que sorprende especialmente con computer use, una vuelta de tuerca más para la automatización de tareas con nuestro ordenador. Es increíble que hace sólo unos meses, todas estas novedades que van apareciendo sólo podrían haber cabido en la ciencia ficción...

También muy interesante el movimiento de JetBrains, facilitando el uso gratuito de sus IDEs WebStorm y Rider para proyectos no comerciales 🙂

¡Que los disfrutéis!

Por si te lo perdiste...

.NET Core / .NET

martes, 22 de octubre de 2024
Imagen decorativa sugiriendo sistemas de almacenamiento en la nube

Una de las novedades más destacables de .NET 9 es, sin duda, el nuevo sistema de caché híbrida (Hybrid cache), una puesta al día del sistema de caché distribuida que nos acompaña desde las primeras versiones de .NET Core, y al que iban haciendo falta ya algunas mejoras.

Este nuevo sistema está construido encima de la infraestructura de caching existente (Microsoft.Extensions.Caching), añadiendo mejoras que hacen que su uso sea más sencillo y contemplando de serie funcionalidades que antes nos veíamos obligados a implementar manualmente.

Vamos a echarle un vistazo a sus principales características :)

Disclaimer: lo que vamos a ver a continuación está basado en .NET 9 RC2, por lo que todavía es posible que haya cambios en la versión final.

lunes, 21 de octubre de 2024
Enlaces interesantes

Como todos los principios de semana, aquí va la lista de enlaces recopilados durante los últimos siete días. Hay bastantes cosas que me han llamado la atención en esta ocasión; entre otros, he descubierto que Visual Studio incluye un visualizador de JWT integrado, el atributo [OverloadResolutionPriority] de .NET 9/C#13, y también me he preguntado cuántos son muchos índices en una tabla SQL 😕

Por si te lo perdiste...

.NET Core / .NET

martes, 15 de octubre de 2024
.NET 9 apareciendo en el horizonte

Cada vez que llega una nueva versión del framework, todos estamos ansiosos por conocer las novedades, especialmente las más espectaculares. Sin embargo, a veces hay pequeñas mejoras que, sin ser revolucionarias, nos pueden resultar útiles en algunos escenarios.

El modificador params permite especificar que un método o función acepta un número variable de argumentos, como en el siguiente ejemplo, donde vemos una función Sum() que puede ser invocada con cualquier número de valores:

// Declaración de la función:
int Sum(params int[] values) 
{
    return values.Sum();
}

// Ejemplos de uso:
Console.WriteLine(Sum(1)); // Enviamos un único valor -> "1"
Console.WriteLine(Sum(1, 2, 3, 4, 5)); // Enviamos cinco valores -> "15"
Console.WriteLine(Sum()); // No enviamos elementos, se recibirá un array vacío -> "0"
Console.WriteLine(Sum([1, 2, 3])); // Aquí pasamos un array directamente -> "6"

Hasta ahora, el parámetro param sólo podía ser un array, lo que limitaba un poco su uso. Por ejemplo, no podríamos llamar a la función Sum() pasándole directamente un List<int> o un IEnumerable<int> sin convertirlos antes a array porque fallarían en tiempo de compilación, al no tratarse de un int[], que es el tipo del parámetro esperado.

¿Qué ha cambiado?

lunes, 14 de octubre de 2024
Enlaces interesantes

Aquí tenemos la recopilación de enlaces de la semana. Entre ellos, me han llamado especialmente la atención los datos que muestra Trevor I. Lasn en su artículo sobre el factor edad en el mundo tecnológico, probablemente porque estoy en el 15% del que habla, los desarrolladores que vuelan ya por encima de los 45 tacos 😆

Y aparte, como siempre, un poco de ASP.NET Core, datos, IA, programación web y otros temas que espero que os resulten interesantes 🙂

Por si te lo perdiste...

.NET Core / .NET

martes, 8 de octubre de 2024
Imagen de una fábrica creando GUIDs

Probablemente, todos hemos usado en algún momento el método Guid.NewGuid() de .NET para generar identificadores únicos globales. Y muchos hemos sufrido con el problema que supone su (pseudo) aleatoriedad, principalmente cuando necesitamos ordenarlos... sobre todo si su destino final es acabar siendo el campo clave de una base de datos relacional.

Pero pocos éramos conscientes de que el método Guid.NewGuid() de .NET retorna un GUID versión 4, y que existen otras versiones de UUID (¡hasta 8!) que pueden resultar más beneficiosas en determinados escenarios.

lunes, 7 de octubre de 2024
Enlaces interesantes

Una semana más, aquí tenéis los enlaces recopilados durante la semana pasada, con mucho protagonismo de los últimos lanzamientos de OpenAI que, si usáis sus APIs o planeáis hacerlo, seguro que os interesarán: la API realtime y el prompt caching

Por si te lo perdiste...

.NET Core / .NET

martes, 1 de octubre de 2024
Imagen decorativa mostrando una jeringa inyectando algo en un circuito

Como sabemos, una forma habitual de registrar servicios en el contenedor de dependencias de .NET consiste en indicar al framework la implementación de la interfaz o clase abstracta que debe ser utilizada cuando se solicite una instancia de la misma. Por ejemplo, en el siguiente código, que podría pertenecer a la inicialización de una aplicación ASP.NET Core, se registra la implementación FriendDbRepository para la interfaz IFriendRepository con un ámbito scoped o por petición:

builder.Services.AddScoped<IFriendRepository, FriendDbRepository>();

Hecho esto, podríamos solicitar una instancia de IFriendRepository en cualquier parte de nuestra aplicación que admita inyección de dependencias, como los controladores, manejadores Minimal API, otras dependencias, etc. El inyector encargará de proporcionarnos una instancia de FriendDbRepository allá donde la necesitemos:

public class FriendsController: Controller
{
    public FriendsController(IFriendRepository friendRepository)
    {
        // ... Aquí la tenemos!
    }
}

O bien, podríamos obtenerla directamente desde la colección de servicios:

public void DoSomething(IServiceProvider services)
{
    var repo = services.GetRequiredService<IFriendRepository>();
    ...
}

Como vemos en ambos casos, la única forma disponible para identificar el servicio que deseamos obtener es utilizar su tipo, o muy habitualmente, la abstracción (interfaz o clase abstracta) a la que está asociado.

Pero eso cambió con la llegada de .NET 8...