Mucho contenido interesante en la última recopilación del año 🙂
Me ha alegrado verde nuevo a Juan María Hernández que, tras algunos años de parón, vuelve con una reflexión bastante certera sobre por qué el proceso de desarrollo es cada vez más lento y costoso conforme los productos van creciendo en complejidad. Os recomiendo su lectura.
También me ha parecido interesante el artículo de Alexey Fedorov sobre el devastador efecto de una estampida en la caché de nuestras aplicaciones, junto con algunas estrategias para evitarlo.
El proyecto MinimalWorker, de Joshua Jesper Krægpøth Ryder, puede resultar útil para reducir significativamente el boilerplate necesario para registrar workers en aplicaciones ASP.NET Core y .NET.
Vladan Petrovic nos muestra TUnit, un nuevo framework de testing para .NET que promete ser una alternativa interesante a los ya existentes.
Y, como siempre, vale la pena leer a Derek Comartin, esta vez reflexionando sobre por qué los debates sobre si debemos usar o no microservicios suelen perder el foco del verdadero problema que se intenta resolver: el acoplamiento.
Por último, como este será el último recopilatorio hasta la vuelta de las fiestas navideñas, aprovecho para desearos a todos unas felices fiestas y un próspero año nuevo 2026.
Por si te lo perdiste...
- Otras formas de obtener dependencias en controladores ASP.NET Core MVC
José M. Aguilar - Propiedades parciales en C# 13 y .NET 9
José M. Aguilar
.NET
- Custom Scripting for Web Applications
Nevio Medancic, Enzo Grubisa & Vassili Kaplan - Dynamically Changing Decimal & Thousand Separators At Runtime
Conrad Akunga - TUnit: The New Sheriff in Town for .NET Testing
Vladan Petrovic - Refactoring Legacy C# Codebases: Modernizing Async, Collections, and Architecture for Safe, Maintainable .NET
Sudhir Mangla - C# Tip How to create and access custom C# Attributes by using Reflection
Davide Bellone - Creating a .NET CLR profiler using C# and NativeAOT with Silhouette
Andrew Lock - .NET Job Scheduling — Choosing the Right Framework
Martin Stühmer - New in .NET 10 and C# 14: Optimizations in log aggregation jobs
Ali Hamza Ansari - Angular Signals, But Better Now for .NET
I Looked Inside .git and You Won't Believe What I Found - How to Analyse Large CSV Files with Local LLMs in C# (English)
Scott Galloway - Stop Typing: The .NET CLI Tab Completion You've Been Missing
Martin Stühmer - Flatten your models with Facet .NET
Tim Maes - Fetching and Analysing Web Content with LLMs in C#
Scott Galloway - Streams Record Truth. Queues Do Work: A .NET Way To Keep Them Straight
Christopher Johnson - Your cache is not protected from cache stampede
Alexey Fedorov - The New Features and Enhancements in .NET 10
Joydip Kanjilal
Publicado por José M. Aguilar a las 8:05 a. m.
Etiquetas: enlaces
La relación de muchos desarrolladores con las expresiones regulares es de amor-odio. Aunque indudablemente son una herramienta muy potente, su uso puede ser complicado y a menudo se convierten en un dolor de cabeza.
Pero hoy no vamos a hablar de su (oscura) sintaxis, ni de lo difícil que es depurarlas, ni de cómo utilizarlas en .NET, sino de distintas técnicas que pueden ayudarnos a disparar su velocidad de proceso, algo bastante importante si las utilizamos en los procesos críticos o hot paths de nuestra aplicación.
En este artículo vamos comparar el rendimiento de distintos escenarios de uso de expresiones regulares, y cómo podemos optimizar su uso en .NET.
La semana pasada estuve unos días fuera y no publiqué la habitual recopilación de los lunes. Pero ya me he puesto al día, y, como se me acumuló el trabajo, en esta entrega tenemos más de ¡100! enlaces a contenidos a los que vale la pena echar un vistazo.
Por destacar algunos, en primer lugar el profundo análisis que está llevando a cabo Martin Stühmer sobre soluciones de scheduling en .NET, muy interesantes para estar al tanto de las opciones disponibles.
También Gerson Azabache ha publicado varios artículos interesantes sobre ASP.NET Core, como la comparativa entre Minimal APIs y controladores, resultados tipados y algunas buenas prácticas en el desarrollo de APIs empresariales.
Braulio Díez comparte sus reflexiones y experiencias sobre el impacto de la IA en la programación y el futuro de los desarrolladores de software, que igual no es tan malo como algunos pintan.
Y en la misma línea, José Manuel Alarcón habla sobre cómo los juniors deben enfocar su proceso de aprendizaje, integrando la IA como una aliada imprescindible.
Muchos más enlaces, a continuación.
Por si te lo perdiste...
- Mi controlador tiene muchos parámetros en el constructor, ¿estoy haciendo algo mal?
José M. Aguilar - HybridCache, la nueva caché híbrida de .NET 9
José M. Aguilar
.NET
- C# 14 New Feature: Field-Backed Properties
Ian Griffiths - Recent updates to NetEscapades.EnumGenerators: [EnumMember] support, analyzers, and bug fixes
Andrew Lock - “Classic” .NET Domain Events with Wolverine and EF Core
Jeremy D. Miller - .NET Job Scheduling: Quartz.NET for Enterprise Scale & Coravel and Fluent Simplicity & NCronJob and Native Minimalism & TickerQ and Modern Architecture
Martin Stühmer - How to Build a Production-Ready Invoice Builder in .NET Using IronPDF
Anton Martyniuk - How can my process read its own standard output?
Raymond Chen - Mime Type Helper in .NET 11
Steven Giesel - Single File Test Suites in Dotnet Csharp
Steve Smith - Create Types on Demand and Cecilifier
Roman Stoffel - Creating a custom MSBuild SDK to reduce boilerplate in .NET projects
Gérald Barré - Debug Dumps in Visual Studio
Stephen Cleary - Building Modular .NET Applications with CShells
Sipke Schoorstra - .NET 10 Networking Improvements
Marie Píchová - What the heck is a
\\.\nulpath and why is it breaking my Directory Files Lookup?
Rick Strahl - .NET 10 Validation
Ricardo Peres - .NET Performance: Efficient Async Code
Nick Kovalenko - .NET 10 and Memory: Less Heap, Smarter GC, Faster Apps
Hazem Ali - Immutable Collection Add() Trap: Don’t Get Burned — Use a Builder Instead
David McCarter - How .NET 10.0 boosted AIS.NET performance by 7%
Ian Griffiths - Resolving Overload Ambiguity with Collection Expressions
Gérald Barré - Typemock Architecture: Inside the .NET Isolator Engine (Part 2)
Eli Lopian - Cleaner Code: C# 14 Null-Conditional Assignment Operator
Dave Brock
Al desarrollar aplicaciones ASP.NET Core (APIs, MVC, Razor Pages o Blazor) y ejecutarlas en local, ya sabes que todas ellas comparten el mismo nombre de host: localhost, y lo único que las diferencia es el puerto en el que se encuentran a la escucha.
Esto puede dar lugar a ciertos problemas. Aparte de no ser sencillo identificarlas a partir de la URL mostrada en el navegador, hay ciertos recursos web que pueden mezclarse entre proyectos (por ejemplo, las cookies) y pueden dar lugar a comportamientos inesperados.
En ASP.NET Core 10 se ha puesto solución a esto añadiendo el soporte para el TLD (Top Level Domain) .localhost, lo que permite que cada aplicación pueda tener su propio nombre de host único.
Lo vemos a continuación.
Soporte para TLD .localhost en ASP.NET Core 10
El nombre .localhost es un dominio de nivel superior (TLD, Top Level Domain) reservado por las RFC 2606 y 6761 para ser utilizado en entornos de desarrollo y pruebas, y siempre está asociado a la dirección de loopback, es decir, a la dirección local del propio equipo.
Por tanto, cualquier nombre de host que termine en .localhost (por ejemplo, miapp.localhost, api.localhost, MyApp.dev.localhost, etc.) debería resolverse siempre a la dirección IP 127.0.0.1 o ::1, dependiendo de si se utiliza IPv4 o IPv6.
A partir de ASP.NET Core 10, Kestrel entenderá que todos los nombres de host que terminen en .localhost son alias válidos para localhost, por lo que podemos utilizarlos para configurar el servidor, definir las URLs de nuestras aplicaciones (tanto en launchSettings.json como en variables de entorno), etc. Esto nos permitirá usar distintos nombres de host para cada aplicación, evitando los problemas mencionados anteriormente.
Otro tema que han actualizado es el certificado HTTPS utilizado en desarrollo. Dado que el antiguo certificado solo era válido para localhost, al utilizar otros nombres de host el navegador mostraría advertencias de seguridad. Por esta razón, el certificado que se registra al instalar .NET 10 es un wildcard del dominio *.dev.localhost.
Observad que no han podido hacerlo directamente para soportar
*.localhost. Han tenido que introducir el subdominio.devpor delante porque no es posible crear wildcards sobre top level domains comolocalhost.
En la práctica, esto implica que podremos asignar a nuestras aplicaciones ASP.NET Core nombres de host como miapp.dev.localhost, api.dev.localhost, etc., aunque no es algo que esté habilitado por defecto.
Para activar esta característica, debemos seleccionar la opción "Use the .dev.localhost TLD in the application URL" al crear una nueva aplicación, como se muestra en la siguiente imagen:
Al hacerlo, se configurará el launchsettings.json para que utilice el nombre de proyecto como subdominio. Por ejemplo, a continuación se muestra la configuración generada para el proyecto MyWebApplication, donde podemos ver el uso del host mywebapplication.dev.localhost:
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://mywebapplication.dev.localhost:5244",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://mywebapplication.dev.localhost:7279;
http://mywebapplication.dev.localhost:5244",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
También podemos conseguir lo mismo si utilizamos la línea de comandos de .NET para crear los proyectos. Por ejemplo, el siguiente comando crea una aplicación MVC que utiliza el TLD .dev.localhost:
C:\MyProjects\MyWebApp>dotnet new web --localhost-tld
The template "ASP.NET Core Empty" was created successfully.
Processing post-creation actions...
Restoring C:\MyProjects\MyWebApp\MyWebApp.csproj:
Restore succeeded.
C:\MyProjects\MyWebApp>type .\Properties\launchSettings.json
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://mywebapp.dev.localhost:5024",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://mywebapp.dev.localhost:7125;
http://mywebapp.dev.localhost:5024",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
C:\MyProjects\MyWebApp>_
Con estas configuraciones, al lanzar el proyecto se utilizarán estos nombres de host exclusivos para el proyecto, evitando los problemas de compartir el mismo localhost entre varias aplicaciones.
C:\MyProjects\MyWebApp> dotnet run
Using launch settings from C:\MyProjects\MyWebApp\Properties\launchSettings.json...
Building...
info: Microsoft.Hosting.Lifetime[14]
Now listening on: http://mywebapp.dev.localhost:5024
info: Microsoft.Hosting.Lifetime[14]
Now listening on: http://localhost:5024
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: C:\MyProjects\MyWebApp
_
Un último detalle importante: podremos utilizar los nombres de host personalizados cuando accedamos a las aplicaciones desde el navegador web, pero probablemente no desde otras herramientas como curl, Postman, etc., o al menos de directamente.
Esto se debe a que, aunque el TLD .localhost está reservado para este propósito, no todas las aplicaciones cliente o los sistemas operativos resuelven automáticamente estos nombres a la dirección de loopback. Por esta razón, en estos casos tendríamos que añadir entradas manuales en el archivo hosts de nuestro sistema operativo para que los nombres personalizados funcionen correctamente.
Afortunadamente, los navegadores web modernos implementan esta resolución de forma automática, por lo que funcionará directamente 🙂
Publicado en Variable not found.
Esta semana me gustaría destacar en primer lugar el detallado análisis de Andrew Lock sobre el proceso de arranque de una aplicación .NET, muy interesante para saber cómo funcionan las cosas por dentro.
Bipin Joshi da un gran repaso a Kestrel, el motor de todas las aplicaciones ASP.NET Core: cómo configurarlo, tunearlo, ejecutarlo y buenas prácticas de uso.
Milan Jovanović nos recuerda que el happy path no es el único camino en nuestras aplicaciones, y nos muestra técnicas para desacoplar servicios para hacerlos más robustos.
Por último, Ricardo Peres nos habla de la relación entre tipos anulables y miembros requeridos en C#, algo que, cuando empezamos a trabajar con ellos, puede resultar algo confuso.
El resto de enlaces, a continuación.
Por si te lo perdiste...
- Soporte para colecciones en parámetros
paramde .NET 9
José M. Aguilar - Establecer textos por defecto y localizados en validaciones de ASP.NET Core MVC
José M. Aguilar
.NET
- TUnit — Why I Spent 2 Years Building a New .NET Testing Framework
Tom Longhurst - C# 14: User-Defined Compound Assignment Operators
Anthony Giretti - Under Pressure: How Queueing Systems Handle Backpressure with Examples in C#
Scott Galloway - Precision Matters in C#: Correctly Handling Money, Time Zones, and Date Ranges
Sudhir Mangla - Exploring the .NET boot process via host tracing
Andrew Lock - .NET Job Scheduling — The Landscape
Martin Stühmer - Why Do You Need To Write Architecture Tests in .NET
Anton Martyniuk - Fetching GitHub content from C#
Thomas Ardal - Using CSX Scripts for Quick C# Testing (English)
Scott Galloway - The Worst Security Vulnerability in Akka.NET
Aaron Stannard - IDistributedCache (Redis)
Josef Ottosson - Adding Intelligence to Blazor with Telerik Smart Components
Héctor Pérez - How to ensure your expert C# knowledge doesn't make you a TypeScript noob
Lewis Cianci - Ix.NET v7.0: .NET 10 and LINQ for IAsyncEnumerable<T>
Ian Griffiths - Real-Time Recommendation Engines in .NET: Hybrid Retrieval, Deep Learning, and Vector Search
Sudhir Mangla - One shot tool execution in .NET 10
Bart Wullems - .NET Job Scheduling — Hangfire and Persistent Reliability
Martin Stühmer - Nullable and Required Types
Ricardo Peres - Unit Testing HttpClient WITHOUT Mocks
Scott Galloway

