Seguro que habéis visto más de una vez un código parecido al siguiente, en el que llamamos a una API REST externa y su resultado es deserializado a un objeto .NET para introducirlo en el flujo de la aplicación:
async Task<User[]> GetUsersAsync()
{
var httpClient = _httpClientFactory.CreateClient();
// Hacemos la llamada
var response = await httpClient.GetAsync("https://jsonplaceholder.typicode.com/users");
// Si la cosa no fue bien, retornamos
if (!response.IsSuccessStatusCode)
return Array.Empty<User>();
// Descargamos la respuesta y la deserializamos
var usersAsJson = await response.Content.ReadAsStringAsync();
var users = JsonSerializer.Deserialize<User[]>(usersAsJson);
return users;
}
Fijaos que el JSON de la respuesta de la API lo guardamos en una cadena de caracteres para, justo después, deserializarlo y convertirlo en un array de objetos User
. Que levante la mano el que no lo haya hecho nunca 😉
¿Y veis dónde está el problema? A la salida de este método, tendremos en memoria dos copias de los datos de los usuarios, una en forma de string
JSON y otra en el objeto que hemos deserializado.
Si estamos hablando de respuestas pequeñas o con poca concurrencia, probablemente el impacto es inapreciable. Pero si las estructuras retornadas por la API tuvieran un tamaño considerable o estamos en un escenario de múltiples llamadas simultáneas, esta duplicidad sería un auténtico derroche de recursos.
Publicado por José M. Aguilar a las 8:00 a. m.
Etiquetas: .net, rendimiento, trucos
Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- Expresiones new con el tipo de destino en C# 9
José María Aguilar - ¿Esa enumeración está vacía?
José María Aguilar
.NET Core / .NET
- El inyector de dependencias de .Net
Fernando Escolar - Consideraciones al publicar un paquete NuGet
Iván Montilla - Missing Stack trace when eliding the await keyword
Steven Giesel - Using the new configuration binder source generator: Exploring the .NET 8 preview
Andrew Lock - Log4net Appenders Introduction With C# Examples
Muhammed Saleem - How to Use Factory Pattern With Dependency Injection in .NET
Ahsan Ullah - 7 Things about C#: Console I/O
Joe Mayo - Microsoft .NET Code Analysis: Always Add Braces in C#
David McCarter - Test Data Generation With AutoFixture in .NET
Code Maze - Rx.NET v6.0: Enhancing Compatibility, Trimming Support, and Many More
Almir Vuk - LINQ: Select.Where or Where.Select?
Steven Giesel - Using Explicit Operators in Microsoft .NET to Perform Type Conversions
David McCarter - How to Hash Passwords with BCrypt in C#
Claudio Bernasconi - Introduction to .NET Releases And Updates
Aram Tchekrekjian - How to Generate C# Business Object Class from a CSV File
Greg Lutz
Cuando en ASP.NET Core MVC usamos rutado por convención, lo habitual es que accedamos a las acciones mediante rutas definidas en el patrón, como [controller]/[action]
. Así, podemos encontrarnos con rutas como /PendingInvoices/ViewAll
para acceder a la siguiente acción:
public class PendingInvoicesController : Controller
{
public IActionResult ViewAll() => Content("Show all pending invoices");
}
Lo mismo ocurre con páginas Razor. Si usamos las rutas por defecto, al archivo /Pages/ShowAllPendingInvoices.cshtml
podríamos acceder mediante la ruta /ShowAllPendingInvoices
. No es que sean rutas terribles, pero tampoco podemos decir que sean lo mejor del mundo en términos de legibilidad y conveniencia.
El kebab-casing consiste en separar con un guion "-" las distintas palabras que componen los fragmentos de la ruta, por lo que en los casos anteriores tendríamos /pending-invoices/view-all
y show-all-pending-invoices
, algo bastante más legible, elegante, y apropiado desde el punto de vista del SEO.
El nombre kebab-casing viene de que visualmente el resultado es similar a un pincho atravesando trozos de comida. Imaginación que no falte 😉
En este post vamos a ver cómo aprovechar los puntos de extensibilidad del sistema de routing de ASP.NET Core para modificar la forma en que genera rutas y así adaptarlo a nuestras necesidades.
Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- Creando gráficas estadísticas en Blazor con los componentes visuales de Syncfusion
José María Aguilar - 30 Leyes epónimas relacionadas con el desarrollo de software (I)
José María Aguilar
.NET Core / .NET
- Introducing the New T4 Command-Line Tool for .NET
Mike Corsaro - Seamless Integration Testing With WireMock.NET
Code Maze - C# 12: Collection literals
Steven Giesel - Wolverine 1.0 is Out! & Wolverine’s Middleware Strategy is a Different Animal
Jeremy D. Miller - Differences Between ExpandoObject, DynamicObject and dynamic
Code Maze - How to use RuntimeHelpers.IsReferenceOrContainsReferences to micro-optimize collections
Gérald Barré - C# Source Code Generators
Bruno Sonnino - C# Struct vs Class: Decoding Key Differences and Use Cases
Wade Gausden - Learn how to mock your HttpClient in C# now with 2 simple methods
Henrique Dalcin Dalmas - Microsoft Forms Service’s Journey to .NET 6
Ray Yao - Validating nested DataAnnotation IOptions recursively with MiniValidation
Andrew Lock - Using StringBuilder To Replace Values
Khalid Abuhakmeh - Parsing websites in C# with Html Agility Pack or AngleSharp
Thomas Ardal - Create your own Mediator (like Mediatr)
Steven Giesel - Getting the .NET Desktop Runtime Installed with a Custom Runtime Checker and Installer
Rick Strahl - Improved .NET Debugging Experience with Source Link
Patrick Smacchia - 7 Things about C#: Running Apps
Joe Mayo - Permutations of a String in C#
Matjaz Prtenjak - Five Reasons Why I Love HangFire
Kevin W. Griffin - Value Objects in C#
Code Maze
Desde la aparición de los nullable reference types, o tipos referencia anulables, en C# 8, nos encontramos frecuentemente con el warning de compilación CS8618, que nos recuerda que las propiedades de tipo referencia definidas como no anulables (es decir, que no pueden contener nulos) deben ser inicializadas obligatoriamente porque de lo contrario contendrán el valor null
, algo que iría en contra de su propia definición.
Para verlo con un ejemplo, consideremos una aplicación de consola con el siguiente código:
var friend = new Friend() {Name = "John", Age = 32};
Console.WriteLine($"Hello, {friend.Name}");
public class Friend
{
public string Name { get; set; }
public int Age { get; set; }
}
La aplicación se ejecutará sin problema, aunque al compilarla obtendremos el warning CS8618:
D:\Projects\ConsoleApp78>dotnet build
MSBuild version 17.4.1+9a89d02ff for .NET
Determining projects to restore...
Restored D:\Projects\ConsoleApp78\ConsoleApp78.csproj (in 80 ms).
D:\Projects\ConsoleApp78\Program.cs(8,19): warning CS8618: Non-nullable property 'Name'
must contain a non-null value when exiting constructor. Consider declaring the
property as nullable.
[...]
[D:\Projects\ConsoleApp78\ConsoleApp78.csproj]
1 Warning(s)
0 Error(s)
Time Elapsed 00:00:02.63
D:\Projects\ConsoleApp78\ConsoleApp78>_
También en Visual Studio podremos ver el subrayado marcando la propiedad como incorrecta:
Aunque muchas veces este warning viene bien porque nos ayudará a evitar errores, hay otras ocasiones en las que puede llegar a ser molesta tanta insistencia. Y en estos casos, ¿cómo podemos librarnos de este aviso?
Disclaimer: algunas de las soluciones mostradas no son especialmente recomendables, o incluso no tienen sentido en la práctica, pero seguro que son útiles para ver características de uso poco habitual en C#.
Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- Crear manualmente instancias de clases usando el proveedor de servicios de .NET
José María Aguilar - PremoniSense, la gran novedad de Visual Studio 2010
José María Aguilar
(¿No era este post una premonición en sí mismo? :D)
.NET Core / .NET
- Announcing .NET 8 Preview 5
Jiachen Jiang - 12: Primary constructor on classes and struct
Anthony Giretti - Optional DependencyInjection in .NET
Federico Alterio - Introduction to Firebase in .NET
Phil Broderick - Collatz sequences by function composition
Mark Seemann - C# Tip: Use custom Equality comparers in Nunit tests
Davide Bellone - How does List work under the hood in .NET?
Steven Giesel - How to detect heap allocations
Bart Wullems