
Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- Raw string literals en C# 11
José María Aguilar - Desacoplando controladores ASP.NET MVC, paso a paso
José María Aguilar
.NET Core / .NET
- Avoiding performance pitfalls in incremental generators: Creating a source generator, part 9
Andrew Lock - Authenticating a .NET GitHub App using a JSON Web Token (JWT)
Steve Gordon - An alternative to AutoMapper
Steven Giesel - Difference between CultureInfo.Get and new CultureInfo
Gérald Barré - Converting String to Byte Array in C#
Caleb Okechukwu - Going Native
Cory Smith - How to Save a List to a Text File in C#
Code Maze - What Does yield Do In C#: A Simplified View For Beginners
Nick Cosentino - What We Are Doing Wrong with Logging in C#
Mabrouk Mahdhi - Interceptors – Using C# 12 in Rider and ReSharper
Khalid Abuhakmeh - Mocking GraphQL queries with WireMock.NET
Cezary Piątek - How to Ensure a String Is Valid JSON in C#
Code Maze - 3 Simple Steps to Split an Excel File into Multiple Excel Files in C#
Mohan Chandran - Plugin Architecture Pattern in C#
Alvaro Montoya - How to Create a Temp File in the Temp Folder in C#
Code Maze - A replacement for BinaryFormatter in .NET 8
Steven Giesel
Publicado por José M. Aguilar a las 8:05 a. m.
Etiquetas: enlaces

Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- PeriodicTimer: Temporizadores asíncronos en .NET 6
José María Aguilar - 101 nuevas citas célebres del mundo de la informática (¡y van 404!)
José María Aguilar
.NET Core / .NET
- GitHub - praeclarum/1brc: The One Billion Row Challenge
Frank A. Krueger - Making primary constructor parameters read-only
Gérald Barré - Consistent Byte Representation of Strings in C# Without Encoding
Code Maze - Throw ThrowIfCancellationRequested in a Method that Returns a Value when Using a Cancellation Token
Bryan Hogan - Coravel - Easy task scheduling for your .NET web apps
Jon Hilton - A brief look at StringValues
Andrew Lock - Const strings are not so const after all
Steven Giesel - Some Stream.Read Guidelines
Mark Heath - Using implicit conversion operators in C# to improve readability
Henrique Dalcin Dalmas - When to Use Thread.Sleep, When to Use Task.Delay?
Code Maze - How to Distribute Roslyn Analyzers via NuGet
Aaron Stannard

Primero, espero que hayáis disfrutado las fiestas y que el 2024 que acabamos de estrenar venga bien cargado de cosas buenas 🙂
Y para inaugurar el año, como cada primer post de enero, aprovecharemos para revisar las diez publicaciones más leídas durante los últimos 365 días.

Ante todo, aprovecho para desearos felices fiestas y, como no nos veremos por aquí hasta enero, un grandioso 2024.
Y, por supuesto, ahí van los enlaces recopilados durante la semana pasada que, como siempre, espero que os resulten interesantes. :-)
Por si te lo perdiste...
- Cómo recibir un JSON como string en una acción ASP.NET Core MVC
José María Aguilar - ¿Por qué separamos los directorios con la barra invertida?
José María Aguilar
.NET Core / .NET
- FluentResults: Simplificando el Manejo de Resultados y Errores en Aplicaciones .NET
Isaac Ojeda - Customize the HttpClient logging
Josef Ottosson - Using the CLI to Build and Run .NET Applications
Dusko Mirkovic - Validating appsettings becomes much faster with .NET 8
David Grace - Custom Naming Policy for JSON in C#
Tomas Bak - Top 6 Performance Tips when dealing with strings in C# 12 and .NET 8
Davide Bellone - Updates to the StronglyTypedId library - simplification, templating, and CodeFixes: Using strongly-typed entity IDs to avoid primitive obsession
Andrew Lock - MemoizR - Declarative Structured Concurrency for C#
Khalid Abuhakmeh - Introduction to Autofac FakeItEasy Package
Ainea Wabwoba - What User Interface Framework Should You Choose for .NET Desktop Applications?
Claudio Bernasconi - Discriminated Unions in C#
Ian Russell - Debugging and Profiling Multithreaded .NET Applications
Code Maze - 5 Serilog Best Practices For Better Structured Logging
Milan Jovanović - What Is String Interpolation In C# – What You Need To Know
Nick Cosentino - What's New in Our Code Coverage Tooling?
Jakub Chocholowicz - The first possible new feature of C# 13: Params collection
Steven Giesel - Execute JavaScript Using Selenium WebDriver in C#
Vadzim Zylevich - Integrating OpenAI Image Generation into a .NET Application
Rick Strahl - A Practical Tour of MoreLINQ
Atif Aziz

Poco a poco vamos haciéndonos con las novedades de C# 12, y en esta ocasión nos centraremos en una nueva sintaxis que proporciona una forma concisa y rápida para declarar los elementos de una colección.
Ya os adelanto que si sois de los que siempre han envidiado otros lenguajes por la facilidad con la que se declaran los elementos de un colección o array, estáis de enhorabuena ;) Porque, sin duda, hay formas de hacerlo menos verbosas que las que hemos tenido hasta ahora en C#:
// JavaScript:
let numbers = [1, 2, 3];
// Python:
numbers = [1, 2, 3]
// PHP:
$array = [1, 2, 3];
// Rust:
let array = [1, 2, 3];
En C# 11 y anteriores, la creación de un array es normalmente más farragosa, porque de alguna forma u otra requiere que especifiquemos que se trata de un nuevo array y, si la inferencia no lo permite, el tipo de los elementos que contendrá:
// Forma verbosa y redundante:
int[] arr1 = new int[3] { 1, 2, 3 };
// Forma clásica, usando 'var' y especificando número y tipo elementos:
var arr2 = new int[3] { 1, 2, 3 };
// Dejamos que el compilador detecte el número de elementos:
var arr3 = new int[] { 1, 2, 3 };
// Dejamos que la inferencia de tipos determine el tipo de los elementos:
var arr4 = new [] { 1, 2, 3 };
// O bien, la más concisa, usando la sintaxis con llaves (sólo válida para arrays):
int[] arr5 = { 1, 2, 3 };

Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- Archivos JavaScript independientes por componente en Blazor
José María Aguilar - Las 20 mejores tiras cómicas sobre desarrollo de software
José María Aguilar
.NET Core / .NET
- Hardware Intrinsics in .NET 8
Tanner Gooding - Tuple Aliases in C#
Aditi Saxena - Where C# Primary Constructors Make Sense
Steve Smith - A Generic Implementation of Dijkstra’s Smoothsort in C#
Jorge Luis Orejel - 5 Things You Need to Know About Aspire and .NET 8
Growth Acceleration Partners - Redacting sensitive data in logs with Microsoft.Extensions.Compliance.Redaction
Andrew Lock - Hosted service has a major update to its lifecycle events
David Grace - 4 ways to create Unit Tests without Interfaces in C#
Davide Bellone - Build Performance Evaluation Workflow with WorkflowEngine in .NET
Aram Tchekrekjian - How to Decode JWT Tokens in .NET
Muhammad Afzal Qureshi - Generic Type Construction With Static Virtual Interface Members
Brant Burnett - Select a Dropdown Option Using Selenium WebDriver in C#
Semir Teskeredzic - C#– Record types copy constructor
Bart Wullems - All Purpose Object Updater
James Curran

Los records son una interesante fórmula para definir tipos en C# de forma rápida gracias a su concisa sintaxis, además de ofrecer otras ventajas, entre las que destacan la inmutabilidad o la implementación automática de métodos como Equals()
, GetHashCode()
o ToString()
.
Por si no tenéis esto muy fresco, aquí va un ejemplo de record y la clase tradicional equivalente en C#:
// Record:
public record Person(string FirstName, string LastName);
// Clase equivalente (generada automáticamente):
public class Person
{
public string FirstName { get; init; }
public string LastName { get; init; }
public Person(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}
public override bool Equals(object obj)
{
return obj is Person person &&
FirstName == person.FirstName &&
LastName == person.LastName;
}
public override int GetHashCode()
{
return HashCode.Combine(FirstName, LastName);
}
public Person With(string FirstName = null, string LastName = null)
{
return new Person(FirstName ?? this.FirstName, LastName ?? this.LastName);
}
public void Deconstruct(out string firstName, out string lastName)
{
firstName = this.FirstName;
lastName = this.LastName;
}
}
Como podéis comprobar, hay pocas características de C# que ofrezcan una relación código/funcionalidad tan bárbara como los records. Por ello, poco a poco van ganando popularidad y comenzamos a verlos ya de forma habitual en código propio y ajeno.
Sin embargo, su concisa sintaxis hacen que a veces no sea fácil intuir cómo resolver algunos escenarios que, usando las clases tradicionales, serían triviales.
Por ejemplo, hoy vamos a centrarnos en un escenario muy concreto pero frecuente, cuya solución seguro que veis que puede ser aplicada en otros casos: ya que en los records no definimos propiedades de forma explícita, ¿cómo podríamos aplicarles atributos?

Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- Llamemos a las cosas por su nombre
José María Aguilar - ASP.NET Core 6, ¿dónde está mi middleware DeveloperExceptionPage?
José María Aguilar
.NET Core / .NET
- .NET 8 Networking Improvements
Máňa & Natalia Kondratyeva - Extending WebAssembly to the Cloud with .NET
Richard Lander - Local Functions in C#
Code Maze - How to Take Advantage of CSharp Optional Parameters for Cleaner Code
Nick Cosentino - How .NET 8.0 boosted JSON Schema performance by 20%
Matthew Adams - Enriching logs with [TagProvider] and ILogEnricher
Andrew Lock - How to use Regular Expressions and Match Evaluators in .NET
Khalid Abuhakmeh - Inline Snapshot testing in .NET
Gérald Barré - Data annotations has some awesome additions in .NET 8
David Grace - Deep C# - Casting the Escape from Strong Typing
Mike James - Learn .NET 8 with New Beginner Videos
Katie Savage - Create Better Looking Console Applications With Spectre.Console
Januarius Njoku - Byte array as a dictionary key? Trying out some options
João Antunes - How to Switch Between .NET SDK Versions
Lennart Pries - .NET Native AOT Explained
NDepend - How to Rename Files in a Folder in C#
Caleb Okechukwu - How to Debug LINQ queries in C#
Michael Shpilt

Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- Cómo saber si un tipo está registrado en el proveedor de servicios de .NET 6, pero sin necesidad de resolverlo
José María Aguilar - Introducción a SignalR (I): Conceptos básicos
José María Aguilar
.NET Core / .NET
- C# 12: todo lo nuevo del lenguaje aparecido con .NET 8
José Manuel Alarcón - Creating Microsoft Teams Applications with Visual Studio and .NET
Anuraj Parameswaran - How to Check if a File Is in Use With C#
Code Maze - Sep 0.3.0 - Unescape Support (still the Most Efficient .NET CSV Parser)
Niels Rasmussen - 5 Awesome C# Refactoring Tips
Milan Jovanović - Behind [LogProperties] and the new telemetry logging source generator
Andrew Lock - Scriban for Text and Liquid Templating in .NET
Khalid Abuhakmeh - Primary constructors has caused concerns for C# developers
David Grace - Embedding a minimal ASP.NET Web Server into a Desktop Application
Rick Strahl - Building resilient cloud services with .NET 8
Martin Tomka - A journey about the new interceptors of .NET 8
Steven Giesel - TDD and refactoring to patterns in C#: how to write a cron parser
Nicolas Descartes - How to Determine the Operating System in .NET Core
Code Maze - How to make libraries compatible with native AOT
Eric Erhardt - Intercepting HTTP requests with a DelegatingHandler
Tim Deschryver - In Defence of Doubles
Anthony Lloyd

Como sabéis, hasta ahora, los componentes Blazor podían ejecutarse en dos tipos de hosting distintos, Blazor Server y Blazor WebAssembly. Aunque cada uno tiene sus escenarios ideales de uso, ambos enfoques conseguían lo mismo, implementar Single Page Applications en C#, sin necesidad de utilizar JavaScript (bueno, o al menos, minimizando radicalmente su uso):
- Con Blazor Server, se mantiene en el servidor una copia del DOM de cada usuario conectado, de forma que C# puede manipularlo directamente. Luego, mediante una conexión websockets, se sincronizan los cambios con el cliente.
- Blazor WebAssembly lleva al navegador el runtime de .NET, las bibliotecas base y los ensamblados de la aplicación, por lo que todo se ejecuta directamente en el lado cliente gracias a WebAssembly.
Estas dos formas de ejecutar componentes son muy apropiadas cuando se trata de elementos interactivos, capaces de responder a eventos de usuarios y con capacidad de actualizar el contenido de la página. Sin embargo, son muy poco eficientes cuando se trata de páginas estáticas que no requieren interacción con el usuario:
-
Para poder mostrar en el navegador un contenido, en Blazor Server hay que esperar a que el lado cliente descargue la página contenedora, un archivo JavaScript y se establezca la conexión websockets con el servidor, tras lo cual se enviará el contenido de la página.
-
En Blazor WebAssembly, el cliente debe descargar la página contenedora, los ensamblados y todo el entorno de ejecución de .NET y lanzarlo todo sobre WebAssembly. En este momento se puede mostrar el contenido de la página.

Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- Declaración de espacios de nombre en una línea con file-scoped namespaces de C#10
José María Aguilar - Establecer el foco automáticamente en MVC, versión declarativa
José María Aguilar
.NET Core / .NET
- .NET 8: Todas las novedades en 2 minutos
José Manuel Alarcón - Announcing .NET Chiseled Containers
Richard Lander - ConcurrentStack in C#
Code Maze - Find a subset from a set of values whose sum is closest to a specific value–C#
Bart Wullems - Intro to .NET and C# - Differences, Structure, SDK, Runtime...
Code Maze - Embedding additional files in an MSBuild binary log file
Gérald Barré - A failed experiment with interceptors in C# 12 and .NET 8
Andrew Lock - Lo-Fi Service Discovery in .NET8
David Whitney - Fake It Til You Make It...To Production
Martin Taillefer - Validating JSON Against a Schema
Paul Michaels - The Differences Between Quartz.NET and Hangfire
Code Maze - Async Lambda Statements
Bryan Hogan - Primary Constructors – Using C# 12 in Rider and ReSharper
Matthias Koch - How To Harness System.Reactive For The Observer Pattern
Nick Cosentino

Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- Curiosidad: ¿Por qué el encabezado 'referer' se llama así, y cómo nos afecta a los desarrolladores .NET?
José María Aguilar - ASP.NET MVC: establecer el foco en un control al cargar la página
José María Aguilar
.NET Core / .NET
- Announcing .NET 8
Gaurav Seth - Announcing C# 12
Kathleen Dollard - Announcing F#
Tomáš Grošup - Removing allocations by reducing closure scopes using local variables
Gérald Barré - The Evolution of C#
Aram Tchekrekjian - Optimizing C# code analysis for quicker .NET compilation
Anthony Simmon - Exploring What's New in C# 12
Darren Horrocks - VestPocket: File-based Data Storage for AOT .NET Applications
Khalid Abuhakmeh - How to Use Interceptors in C# 12
Code Maze - A more flexible and enhanced way of logging in .NET 8
Steven Giesel - How to extract, create, and navigate Zip Files in C#
Davide Bellone - C# Interceptors
Paul Michaels - Enums in CSharp – A Simple Guide To Expressive Code
Nick Cosentino - Alias any Type with C# 12
Michael Jolley - Top 10 Must-Have Features in Syncfusion’s C# PDF Library
Sowmiya Loganathan - Standard and Custom Numeric Format Strings in .NET
Code Maze - The CSharp Switch Statement – How To Go From Zero To Hero
Nick Cosentino

Desde su llegada con la versión 7 del lenguaje C#, allá por 2017, nuestro lenguaje favorito dispone de soporte para tuplas. Sin embargo, no he visto muchos proyectos donde estén siendo utilizadas de forma habitual; quizás sea porque pueden hacer el código menos legible, o quizás por desconocimiento, o simplemente porque lo que aportan podemos conseguirlo normalmente de otras formas y preferimos hacerlo como siempre para no sorprender al que venga detrás a tocar nuestro código.
Pero bueno, en cualquier caso, es innegable que las tuplas han venido para quedarse, así que en este post vamos a ver algunos usos posibles, y a veces curiosos, de esta característica del lenguaje C#.

Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- El atributo CallerArgumentExpression, o cómo conocer las expresiones usadas como argumentos en llamadas a un método en C#
José María Aguilar - Funciones constructoras en Javascript
Oscar Sotorrío
.NET Core / .NET
- Reading a stream of JsonDocuments separated by new lines (ndjson)
Gérald Barré - Merging Multiple PDFs Using the iText Library
Matjaz Prtenjak - The convenience of System.IO
Richard Lander - Pangram validator in one line
Christian Heilmann - Implementing Distributed Locks in .NET Core with Redis or ZooKeeper
Hamed Salameh - MoonSharp - Running Lua Scripts in .NET
Khalid Abuhakmeh - Updates On Microsoft’s BinaryFormatter Obsoletion Strategy
DevExpress Blogs - Provide opt-in to experimental APIs using C#12 ExperimentalAttribute
Maarten Balliauw - Comparing ForEach Method and Foreach Statement in C#
Code Maze - Let’s build a custom Microsoft Graph connector
Waldek Mastykarz - Read and Write Windows Registry in C#
Code Maze - ConfigureAwait in .NET 8
Stephen Cleary - Discovering The Features Of DotNetFiddle – How To Compile C# Online
Nick Cosentino - .NET Task Parallel Library vs System.Threading.Channels
Charles Chen - TimeProvider makes it easier to mock time in .NET 8
David Grace - Automating Memory Profiling with the JetBrains dotMemory Profiler API
Steve Gordon - Interactive LINQ tutorial, especially for beginners
Steven Giesel

El otro día me descubrí escribiendo un código parecido al siguiente:
return $"Order: {Items.Length} items, {Total.ToString("#,##0.#0")}";
Mal, lo que se dice mal, no estaba; funcionaba perfectamente y cumplía los requisitos, pero me di cuenta de que no estaba aprovechando todo el potencial de las cadenas interpoladas de C# que ya habíamos comentado por aquí mucho tiempo atrás.
Y como siempre que tengo algún despiste de este tipo, pienso que quizás pueda haber alguien más al que le ocurra o no esté al tanto de esta posibilidad el lenguaje, así que vamos a ver cómo podíamos haberlo implementado de forma algo más simple.

Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- Cómo evitar que entren argumentos nulos en métodos de C#: un recorrido histórico (y lo que nos trae el futuro)
José María Aguilar - Limpiar un input type=file
José María Aguilar
.NET Core / .NET
- Avoiding flaky tests with TimeProvider and ITimer: Exploring the .NET 8 preview
Andrew Lock - Managing Directories With Directory and DirectoryInfo in C#
Code Maze - Exploring Object Layouts - To kill a mocking bug
Jeroen Vannevel - Functional Error Handling in .NET With the Result Pattern
Milan Jovanović - A C# port of validation with partial round trip
Mark Seemann - Yes you can create classes on the stack!
Steven Giesel - How to Build a Query String for a URL in C#?
Code Maze - Caching your WebView Environment to manage multiple WebView2 Controls
Rick Strahl - Handling Dates With Noda Time in .NET
Code Maze - Collection expressions brings the spread operator to C# 12
David Grace - How to Force Run .NET Application as Administrator
Code Maze - Await Tuples Directly
Mehran Davoudi - Save Files With Elevated Permissions on UnauthorizedAccessException
Rick Strahl

Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- El Tao de la Programación
José María Aguilar - Generación de rutas con parámetros de query string en Blazor 6
José María Aguilar
.NET Core / .NET
- .NET 8 Top 10 New Features
Patrick Smacchia - What′s new in C# 12: overview
Konstantin Volohovsky - Customizing the behavior of record copy constructors
Gérald Barré - Ignore Null Values With AutoMapper
Code Maze - Open-Sourcing Metalama Compiler, a Roslyn Branch with Source Transformers
Gael Fraiteur - How To Handle Exceptions in CSharp – Tips and Tricks for Streamlined Debugging
Nick Cosentino - C# Tip: How to create Unit Tests for Model Validation
Davide Bellone - A Generic Timeout Helper
Ricardo Peres - Interfaces can have private methods
Steven Giesel - Source Code Generators, DIY
Bnaya Eshet - C# Record Explained
Patrick Smacchia
Pues hoy vamos con un truquillo rápido ;)
Como sabemos, cuando usamos Razor Pages para construir aplicaciones sobre ASP.NET Core, la convención por defecto obliga a que nuestras páginas se encuentren en la carpeta /Pages del proyecto.
¿Pero qué ocurre si somos algo tiquismiquis y no nos gusta esa ubicación o no podemos usarla por cualquier motivo? En este post vamos a ver cómo cambiar esta convención para que nuestras páginas Razor se encuentren en otra carpeta.

Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- ¿Por qué no compila este código C#?
José María Aguilar - ASP.NET MVC: obtener id y nombre de un control de formulario
José María Aguilar
.NET Core / .NET
- Customizing the name of embedded resources in .NET
Gérald Barré - Updates to Docker images in .NET 8: Exploring the .NET 8 preview
Andrew Lock - Source Generator playground
Bart Wullems - C# Overtaking Java in Popularity Index
David Ramel - Using Keyed Services to Resolve Dependencies in .NET
Code Maze - Pre-commit hooks with Husky.NET - build, format, and test your .NET application before a Git commit
Davide Bellone - .NET 6 - Parallel.ForEachAsync
Bart Wullems - Microsoft .NET Code Analysis: Remove Unnecessary Lambda Expressions
David McCarter - 3 Reasons to Delay Adopting .NET 8 and 10 to do it ASAP
Uno Platform Team

Sabemos que está feo y no sea especialmente recomendable en muchos casos, pero hay veces en las que es totalmente necesario acceder a miembros privados de una clase. Por ejemplo, sería un requisito imprescindible si fuéramos a implementar un serializador o deserializador personalizado, o necesitásemos clonar objetos, o simplemente realizar pruebas unitarias a una clase que no ha sido diseñada para ello.
Para conseguirlo, siempre hemos utilizado los mecanismos de introspección de .NET, conocidos por todos como reflexión o por su término en inglés reflection. Por ejemplo, imaginemos una clase como la siguiente, virtualmente inexpugnable:
public class BlackBox
{
private string _message = "This is a private message";
private void ShowMessage(string msg) => Console.WriteLine(msg);
public override string ToString() => _message;
}
Aunque a priori no podemos hacer nada con ella desde fuera, usando reflexión podríamos acceder sin problema a sus miembros privados, ya sean propiedades, campos, métodos o cualquier tipo de elemento, como podemos ver en el siguiente ejemplo:
var instance = new BlackBox();
// Obtenemos el valor del campo privado _message:
var field = typeof(BlackBox)
.GetField("_message", BindingFlags.NonPublic | BindingFlags.Instance);
var value = field!.GetValue(instance);
// Ahora llamamos al método privado ShowMessage():
var method = typeof(BlackBox)
.GetMethod("ShowMessage", BindingFlags.NonPublic | BindingFlags.Instance);
method.Invoke(instance, [value]);
// Al ejecutar, se nuestra en consola: "This is a private message"
Sin embargo, de todos es sabido que la reflexión es un mecanismo muy lento, a veces farragoso en su implementación y, sobre todo, incompatible con tree-shaking, que es como se suele llamar la técnica que usan los compiladores de eliminar del código final todas las clases, métodos y propiedades que no se utilizan en el código final. Esta técnica va tomando cada vez más relevancia conforme los compiladores son capaces de crear directamente ejecutables nativos puros, porque permiten reducir de forma considerable el peso de los artefactos creados.
Por esta razón, en .NET 8 se ha incluido una nueva fórmula para acceder a miembros privados, mucho más eficiente y amistosa con AOT, porque se lleva a tiempo de compilación algo que antes obligatoriamente se resolvía en tiempo de ejecución.

Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- El veloz murciélago hindú…
José María Aguilar - Implicit usings en C#10
José María Aguilar
.NET Core / .NET
- Announcing .NET 8 RC2
Jon Douglas - OpenSilver 2.0 released
Userware - Full precision floating-point summation in C#
Anthony Lloyd - Get the default value of a type at runtime
Gérald Barré - Replace Line Breaks in a String in C#
Code Maze - Getting Started With NServiceBus in .NET
Milan Jovanović - Padding for Overlaid Structs
Stephen Cleary - How To Use Embedded Resources in .NET
Khalid Abuhakmeh - Revisiting Various Change Feeds Consumption in .NET
Tomasz Pęczek - xUnit And Moq – How To Master Unit Testing In C#
Nick Cosentino - Lessons learned from building a static code analyzer for C#
Daniel Genezini - Primary constructors changes initialisation behaviour in C# 12
David Grace - Structured Concurrency in C#
Steven Giesel - .NET 8 New and Efficient Way to Check IP is in Given IP Range
Sibeesh Venu - ConcurrentQueue in C#
Michal Kaminski - Simplify Source Generator creation the RoslynGenerator template
Bart Wullems

Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- Lo que ocurre cuando desarrolladores diseñan interfaces de usuario (II)
José María Aguilar - Directivas using globales en C# 10
José María Aguilar
.NET Core / .NET
- Logs en .Net
Fernando Escolar - How to test the logs from ILogger in .NET
Gérald Barré - Testing Time-Dependent Code With TimeProvider in .NET
Code Maze - Performance Improvements in .NET 8
Rico Mariani - Rolling Forward to Major Versions in .NET
Rick Strahl - How To Display .NET Collections with the Oxford Comma
Khalid Abuhakmeh - Selecting Xml Nodes With XPath in C#
Code Maze - Effortlessly Resolving Circular Dependencies in .NET with SmartInject
Daan Acohen - Arm64 Performance Improvements in .NET 8
Kunal Pathak - Don't Use "Task.WhenAll" for Interdependent Tasks
Jeremy Clark - Tales from the .NET Migration Trenches - Our First Views
Jimmy Bogard - The convenience of System.Text.Json
Richard Lander - Looking at Producer/Consumer Dependencies: Bounded vs. Unbounded Channels & Producer/Consumer Exception Handling
- Jeremy Clark

Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- ¿Por qué llamamos "uppercase" y "lowercase" a mayúsculas y minúsculas?
José María Aguilar - 32 Síntomas que indican que estás afectado por el desarrollo
José María Aguilar
.NET Core / .NET
- Polly v8 officially released
Joel Hulen - Wolverine Expands its Multi-Tenancy Story to HTTP
Jeremy D. Miller - Create Cryptographic Numbers With RandomNumberGenerator
Code Maze - How to write logs from ILogger to xUnit.net ITestOutputHelper
Gérald Barré - Less boilerplate code with the new primary constructor in C# 12
Steven Giesel - Don’t persist GetHashCode() in .NET!
Isaac Abraham - The convenience of .NET
Richard Lander - The case of the mysterious comparison
Mark Seemann - C# Tip: Improve memory allocation by initializing collection size
Davide Bellone - Using a Discard Variable in C#
Code Maze - Green Thread Experiment Results
David Wrighton - Debugging Enhancements in .NET 8
James Newton-King - Wolverine Interoperability with Others
Jeremy D. Miller - Memory Optimization With ArrayPool in C#
Code Maze - How To Use BenchmarkDotNet For Beginners
Nick Cosentino - Tales from the .NET Migration Trenches
Jimmy Bogard - Questions I asked as .NET interviewer
Steven Giesel - Memory-Mapped Files and Overlaid Structs
Stephen Cleary - 22 C# Best Practices
Code Maze - How to Add Comments to Excel Documents Using C#
Mohan Chandran

Seguro que más de una vez habéis tenido que construir una abstracción sobre DateTime
para poder controlar apropiadamente la obtención de la fecha/hora actual y otras operaciones relacionadas con el tiempo.
Suelen ser bastante útiles cuando creamos pruebas unitarias de métodos que dependan del momento actual. Por ejemplo, ¿cómo testearíamos de forma automática que las dos líneas de ejecución del siguiente método DoSomething()
funcionan correctamente? Sería imposible salvo que ejecutásemos las pruebas a una hora determinada, algo que se antoja complicado 😉
public class MyClass
{
public string DoSomething()
{
var now = DateTime.Now;
return now.Second == 0
? "A new minute is starting"
: "Current second " + now.Second;
}
}
Sin duda, una forma mejor y más test friendly sería contar con una abstracción sobre el proveedor de tiempos capaz de retornar la fecha y hora actual, por ejemplo:
public interface IDateTimeProvider
{
DateTime GetCurrentDateTime();
}
De esta forma, podríamos reescribir la clase MyClass
de forma que recibiera por inyección de dependencias nuestro proveedor IDateTimeProvider
. Así sería realmente sencillo crear un par de pruebas unitarias que, suministrando los valores correctos a través de esta dependencia, podrían recrear los escenarios a cubrir:
public class MyClass
{
private readonly IDateTimeServices _dateTimeServices;
public TimeHelpers(IDateTimeServices dateTimeServices)
{
_dateTimeServices = dateTimeServices;
}
public string DoSomething()
{
var now = _dateTimeServices.GetCurrentDateTime();
return now.Second == 0
? "A new minute is starting"
: "Current second " + now.Second;
}
}
Aunque hacerlo de esta manera en nuestras aplicaciones es lo ideal, hay partes que se quedarían fuera de esta posibilidad, como las bibliotecas de terceros que de alguna forma dependan de las funcionalidades proporcionadas por DateTime
.
Por esta razón, .NET 8 va a introducir una abstracción que nos permitirá gestionar estos escenarios de forma más homogénea y generalizada en aplicaciones y componentes .NET.
Os presento la clase abstracta TimeProvider
😁

Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- 5 motivos por los que tus acciones MVC reciben objetos vacíos o nulos en ASP.NET Core
José María Aguilar - Validación de peticiones en ASP.NET, o cómo evitar el error “Request.Form peligroso”
José María Aguilar
.NET Core / .NET
- Métricas en .Net
Fernando Escolar - What's new in System.Text.Json in .NET 8
Eirik Tsarpalis - Extending HTTPClient with Custom Http Message Handlers in dotnet
Abdul Rahman - How to Validate JWTs in .NET
Andrea Chiarelli - Sharing WireMock in sequential and parallel tests
Cezary Piątek - Accessing private members without reflection in C#
Gérald Barré - Discriminated Unions in C#
Maarten Balliauw - Back to .NET basics: How to easily build a Strategy pattern using dependency injection
Carlos Pons - Synchronization Mechanisms - Volatile vs Interlocked vs lock in C#
Code Maze - Feature Flags in .NET and How I Use Them for A/B Testing
Milan Jovanović - When to Use ReaderWriterLockSlim Over lock in C#
Code Maze - System.Text.Json JsonConverter Test Helpers
Khalid Abuhakmeh - Feature Flags 101: A Guide for .NET Developers
Davide Bellone - .NET 8–Keyed/Named Services
Bart Wullems - ASCII vs UTF8 - How To Navigate Character Encoding
Nick Cosentino - Different Log Levels in Serilog
Code Maze - Less boilerplate code with the new primary constructor in C# 12
Steven Giesel

La verdad es que este año me ha dado algo de pereza volver a abrir el blog después de este periodo veraniego de descanso. Aunque disfrute escribiendo y compartiendo información, mantener esto medio vivo requiere esfuerzo y tiempo, que obviamente dejo de dedicar a otras cosas que también me gustan 🙂
Pero bueno, la cuestión es que por aquí andamos de nuevo, listos para inaugurar oficialmente la temporada 2023-2024. ¿Y qué mejor forma de hacerlo que con una nueva recopilación de enlaces interesantes? ¡Pues vamos allá!
Por si te lo perdiste...
- CRUD en Blazor usando el componente DataGrid de Syncfusion
José María Aguilar - Parámetros opcionales: úsense con precaución
José María Aguilar
.NET Core / .NET
- Trazas en .Net
Fernando Escolar - Announcing .NET 8 RC1
Leslie Richardson - Performance Improvements in .NET 8
Stephen Toub - Tales from the .NET Migration Trenches, Empty proxy & Shared library
Jimmy Bogard - Working with API that supports remote streaming using HTTPClient in dotnet
Abdul Rahman Shabeek Mohamed - Building a Resilient Email Sending Method in .NET with SmtpClient, Retry Support, and the Outbox Pattern
Steve Smith - Your Quick Guide to Pattern Matching in C#
Aram Tchekrekjian - Listing Windows virtual desktops using .NET
Gérald Barré - File-Scoped Types in C# 11
Code Maze - Dictionaries in C#: How To Use The Different Variations
Nick Cosentino - Dumb Developer Tricks - Fizz Buzz with C# 12 and Polly
Khalid Abuhakmeh - Creating custom debug visualizers for Visual Studio 2022
Thomas Ardal - Techniques for Checking Floating-Point Equality in C#
Code Maze - The best C# REPL is in your terminal
Anthony Simmon - How to Use Moq to Return a Value That Was Passed Into a Method
Code Maze - Reverse engineering natively-compiled .NET apps
Michal Strehovský - Resilient Http Calls using Polly.
Dhananjeyan Balaretnaraja

Si sois habituales del blog, probablemente ya sabréis lo que os voy a decir ;)
Como todos los años por estas fechas, empieza el periodo vacacional y aprovecharé para bajar un poco el ritmo, descansar unos días y disfrutar de familia y amigos.
Por tanto, dejaré el blog en modo de bajo consumo hasta bien entrado septiembre, cuando, ya con las pilas recargadas, volveré al ataque con nuevos artículos y enlaces interesantes. Eso sí, durante este periodo seguiré echando el ojo periódicamente a comentarios o mensajes que me dejéis, aunque no los responderé con la misma celeridad que en otras épocas del año.
Aprovecho para desearos a todos un feliz verano y que disfrutéis de las vacaciones. ¡Nos vemos a la vuelta!
Publicado en Variable not found.

Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- ¿Se pueden crear componentes Blazor que no hereden de ComponentBase o alguno de sus descendientes?
José María Aguilar - Consejos imprescindibles por si algo falla
José María Aguilar
.NET Core / .NET
- The minimal API AOT compilation template: Exploring the .NET 8 preview Part 1 & Part 2
Andrew Lock - TimeProvider and ITimer: Writing Unit Tests with Time in .NET 8 Preview 4
Artur Ampilogov - Roslyn Compiler and Analyzers in .NET
Code Maze - Why I like and prefer xUnit
Steven Giesel - Adding a Readme to NuGet Package Landing Pages
Khalid Abuhakmeh - Finding Symbols in Your C# Projects Using Roslyn
Calvin A. Allen - Converting a Byte Array to Hexadecimal String in C#
Code Maze - Customizing Return Value Behavior in Wolverine for Profit and Fun
Jeremy D. Miller - 7 Things about C#: If Statements
Joe Mayo - Discriminated Unions in C# With OneOf
Ryan Miranda - Improved Source Generators and Code Fixers Arrive in .NET Community Toolkit 8.2.1!
Sergio Pedri - Microsoft .NET Code Analysis: UTF-7 Encoding Is Insecure
David McCarter