Blogger invitado

Jorge Turrado
Apasionado de la programación, siempre buscando la manera de mejorar el día a día con el desarrollo de tecnologías .NET. Apasionado de este momento tan cambiante y fabuloso para ser desarrollador C#.Como desarrollador del ecosistema .NET, seguro que alguna vez has usado el gestor de paquetes NuGet (y si aún no lo has hecho, lo acabarás haciendo antes o después, créeme). Esta herramienta permite empaquetar componentes que cumplen una necesidad determinada, ya sea de terceros o internos de nuestra empresa, dejándolos listos para obtenerlos e incluirlos rápidamente en nuestros proyectos sin tener que compilarlos cada vez o almacenarlos en forma de binarios en una enorme carpeta con cientos de librerías.
Su máximo referente es el repositorio público Nuget.org, integrado dentro de Visual Studio y repositorio de facto de .NET Core, aunque también existen repositorios NuGet privados, o incluso puedes crear el tuyo sin ningún problema bajándote el paquete Nuget.Server desde el propio Nuget.org e implementándolo, ¿es poético verdad? 😊).

Publicado por José M. Aguilar a las 10:00 a. m.
Etiquetas: colaboraciones, jorgeturrado, nuget
Por si te lo perdiste...
- Lambdas como árboles de expresión
José María Aguilar - Usar Razor desde una aplicación de consola .NET Core (2 de 2)
José María Aguilar
.NET / .NET Core
- An update to C# versions and C# tooling
Phillip Carter - DateTime.Now: Usage, Examples, Best Practices, and Pitfalls
Carlos Schults - AKS, KeyVault y netcore
Eduard Tomás - How to Create, Use, and Debug .NET application Crash Dumps in 2019
Michael Shpilt - Creating Custom Web Crawler with Dotnet Core using Entity Framework Core
Mehmet Ozkaya - C# 8.0 in-depth: Setup C# 8.0 and .NET Core 3.0
Dix Yan - An Introduction to Optimising Code Using Span
Steve Gordon - WhiteList Proxying with ASP.Net Core
John Reilly - TransientFaultHandling.Core: Retry library for .NET Core/.NET Standard
Dixin Yan - An example of interaction-based testing in C#
Mark Seemann - Runtime analysis and leak detection for Autofac
Nicholas Blumhardt - C# 8 surprising patterns & Discards and underscores & Tuple deconstruction and positional patterns] & Variable declarations and type patterns
Ian Griffiths - AutoMapper Usage Guidelines
Jimmy Bogard - How to port desktop applications to .NET Core 3.0
Olia Gavrysh - Learning about .NET Core futures by poking around at David Fowler's GitHub
Scott Hanselman - Is C# a low-level language?
Matt Warren

Sin embargo, estas ayudas tienen un coste importante, al igual que ocurre con casi cualquier framework al que vayamos a confiar parte de nuestro sistema, sea del ámbito que sea: hay que conocerlo bien para no dispararse en un pie en cuanto apretemos el gatillo.
Hace muuuuchos, muchos años hablamos de cómo aplicar convenientemente la carga anticipada (eager loading) en Entity Framework podía acelerar de forma drástica el rendimiento en el acceso a datos de nuestras aplicaciones, evitando el temido problema denominado "SELECT N+1". Esto continúa siendo válido para la versión Core de este marco de trabajo: sigue existiendo el extensor
Include()
e incluso variantes de éste como ThenInclude()
que permiten incluir en una única consulta las entidades que sabemos que vamos a necesitar.Pues bien, en EF Core hay otro detalle que, si bien utilizándolo con conocimiento puede resultar muy interesante, es fácil que nos tumbe el rendimiento de nuestros accesos a datos si no lo usamos con cuidado: la evaluación en cliente.
Por si te lo perdiste...
- Expresiones lambda como delegados
José María Aguilar - Capturar la pantalla con Windows 10
José María Aguilar
.NET / .NET Core
- .NET Core 1.0 and 1.1 will reach End of Life on June 27, 2019
Rich Lander - Announcing .NET Framework 4.8 Early Access Build 3745
Namrata Karnam - C# 8 – Introducing Index struct and a brand new usage for the hat operator – Developers Anonymous
John Demetriou - Dynamically compile and run code using .NET Core 3.0
Laurent Kempé - Novedades de C# 8
Fernando Escolar - Novedades de C# 8.0 al escenario
David Gonzalo - Universal hierarchy traversing in C#
Gunnar Peipman - Switching Between .NET Core SDK Versions
Faisal Pathan - Introduction to Benchmarking C# Code with Benchmark .NET
Steve Gordon - .NET Internals Cookbook Part 1 — Exceptions, filters and corrupted processes
Adam Furmanek - C# 8: Default Interface Methods Implementation
Dawid Sibiński - How to exclude code from code coverage
Gunnar Peipman - Heap vs stack, value type vs reference type
Konrad Kokosa - HttpClient Creation and Disposal Internals: Should I Dispose of HttpClient?
Steve Gordon - What's the Difference Between Razor and Blazor?!?
Jason Robert - Dependency Injection for Quartz.NET in .NET Core
Bohdan Stupak - Exploring .NET Core 3.0 new API
Patrick Smacchia
Entre otras, el tag helper
<cache>
es especialmente útil para almacenar en la memoria del servidor el resultado de procesar una porción de página o vista, de forma que pueda ser reutilizada en peticiones siguientes. Un ejemplo bastante básico, pero que deja bastante clara su utilidad y forma de uso, podría ser el siguiente:<h1>Atomic clock</h1>
<cache expires-after="@TimeSpan.FromSeconds(30)">
@{
await Task.Delay(3000);
}
Current time: @DateTime.UtcNow.ToLongTimeString()
</cache>
Al acceder a una vista con el código anterior por primera vez, se producirá un retardo forzado de tres segundos, se renderizará el interior del tag <cache>
mostrando la hora actual, y el resultado será almacenado en memoria durante 30 segundos.Si volvemos a acceder a la misma vista durante esos 30 segundos, el resultado será mostrado inmediatamente (sin esperar los tres segundos) y el cliente recibirá el contenido que se cacheó durante la primera visita. Al transcurrir este plazo, en la siguiente petición se volverá a procesar el contenido del tag helper, ejecutándose la espera y volviendo a generar y cachear el resultado enviado al cliente.
Pero podemos tener ejemplos algo más complejos, como el siguiente. En el interior del tag helper hemos insertado un view component que podría mostrar las últimas noticias obtenidas de una base de datos, en lo que podría ser la página de inicio de un servicio de información on-line:
<section>
<h1>Latest news</h1>
<cache expires-after="@TimeSpan.FromSeconds(30)">
<vc:latest-news></vc:latest-news>
<p>
Updated at: @DateTime.UtcNow.ToLongTimeString()
</p>
</cache>
</section>
Fijaos que en este caso el tiempo de invalidación del contenido almacenado en caché no tendría sentido que fuera periódico: ¿para qué invalidar la caché y volver a obtener las noticias de la base de datos cada X segundos si quizás no se ha introducido ninguna nueva desde la última vez que se renderizó la página? ¿No sería mejor recargar la caché sólo cuando se hayan modificado las noticias?Por si te lo perdiste...
- Usar Razor desde una aplicación de consola .NET Core (1 de 2)
José María Aguilar - C#: Desmitificando las expresiones lambda (I)
José María Aguilar
.NET / .NET Core
- Adapting Projects to Use C# 8 and Nullable Reference Types
Jonathan Allen - NullableAttribute and C# 8
Jon Skeet - Instantiating a C# object from a string using Activator.CreateInstance in .NET
Jeremy Lindsay - Asynchronous Injection
Mark Seemann - Automating .NET Core Services with PostSharp and Aspect-Oriented Code
Alexander Johnston - Readonly ref variables, in parameters and readonly structs
Konrad Kokosa - Size of struct and size of class in .NET
Jiří Činčura - Using declarations in C# 8.0
Gunnar Peipman - Hunting .NET memory leaks with Windbg
André Snede Kock - An Exhausting List of Differences Between VB.NET & C#
Anthony D. Green - Simple Transaction: Microservices sample architecture for .Net Core Application
John-Ph - VB.NET Popularity Still Rising
David Ramel - When to use C# LINQ with Query Syntax over Method Syntax
Michael Shpilt - C# 8: slicing with Indexes and Ranges
Dawid Sibiński - How many keywords I can fit into a single C# expression? – results
Jiří Činčura - Dependency injection in .NET Core console applications
Gunnar Peipman
En este post vamos a ver cómo conseguirlo, y un caso práctico de uso de esta técnica en un escenario muy frecuente.
Publicado por José M. Aguilar a las 8:30 a. m.
Etiquetas: aspnetcore, aspnetcoremvc, patrones, trucos
Por si te lo perdiste...
- 101 formas de saber que tu proyecto está condenado al fracaso
José María Aguilar - Generar redirecciones HTTP 307 y 308 en ASP.NET Core MVC
José María Aguilar
.NET / .NET Core
-
Historia de C#
Fernando Escolar - AppSettings.json, an unfortunate name?
Daniel Wertheim - Advanced C# - Dynamic Type
Marinko Spasojevic - C# 8 is fixing interpolated verbatim strings – Developers Anonymous
John Demetriou - An extension method for .NET enumerations that uses the DescriptionAttribute
Jeremy Lindsay - Fixing Random, part 2
Eric Lippert - Working with types in a Roslyn analyzer
Gérald Barré - C# 8: Nullable Reference Types
Dawid Sibiński - C# Futures: Lambda Attributes & Static Delegates and Function Pointers
Jonathan Allen - How many keywords I can fit into a single C# expression?
Jiří Činčura - New Jasper Alpha for HTTP Services
Jeremy D. Miller - Brainstorming - Creating a small single self-contained executable out of a .NET Core application
Scott Hanselman - How to debug .NET Deadlocks (C# Deadlocks in Depth - Part 3)
Michael Shpilt - Cómo guardar "secretos" en nuestras aplicaciones de .NET Core (sin peligro de enviarlos a GitHub por error)
Jorge Turrado
public class MyCustomMiddleware
{
private readonly RequestDelegate _next;
public MyCustomMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
// Hacer algo antes de pasar el control al siguiente middleware
await _next(context); // Pasar el control al siguiente middleware
// Hacer algo después de ejecutar el siguiente middleware
}
}
Estas clases no heredan de ninguna otra ni implementan interfaces proporcionadas por el framework, aunque atienden a convenciones simples, como la recepción en el constructor del delegado al siguiente middleware en el pipeline, o la existencia de un método Invoke()
o InvokeAsync()
, que es donde introduciremos nuestra lógica, recibiendo el contexto HTTP.La ausencia de interfaces o clases base aporta flexibilidad, pero elimina las ayudas propias del tipado fuerte y puede ser fuente de problemas si no atendemos a estas convenciones con cuidado. Es decir, si en lugar del método
Invoke()
por error escribimos Invke()
, nada fallará en compilación. Tendremos que esperar a ejecutar la aplicación para que explote.También es importante tener en cuenta que una clase middleware sólo es instanciada una vez, cuando la aplicación está arrancando; luego, en cada petición será ejecutado su método
Invoke()
sobre la misma instancia, lo que es a priori muy poco intuitivo y puede causarnos algún dolor de cabeza si no somos cuidadosos.Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- Programadores con producción neta negativa (NNPP)
José María Aguilar - ¿Aún usas ToString() para obtener el nombre de los elementos de un enum?
José María Aguilar
.NET / .NET Core
- Announcing .NET Core 3 Preview 2
Rich Lander - Introducing the .NET Community Standup Series
James Montemagno - Generate disassembly of .NET functions
Wojciech Nagórski - Tic Tac Toe Using AI –The Easy Way
George Swan - Designing Data Objects in C#: More examples
Yacoub Massad - yield return await and await foreach geekery
Jiří Činčura - C# 8 using declarations
Kevin Jones - C# Interface: Definition, Examples, Best Practices, and Pitfalls
Phil Vuollet - System.Collections in .NET Core 3.0
Jonathan Allen - WTF Is a Lambda
Jon Hilton - [C#] Have some fun with .net core startup hooks
Kévin Gosse - Dependency Hell
Damian Laczak - Is WPF Still Relevant in 2019?
Claudio Bernasconi - Update on IAsyncDisposable and IAsyncEnumerator
Jonathan Allen - Fixing random, part 1
Eric Lippert
Como recordaréis, se trata de una mejora en el módulo ASP.NET Core (ANCM) que hace que las aplicaciones se ejecuten directamente dentro del worker del servidor web (w3wp.exe), evitando las llamadas internas producidas cuando IIS actuaba como un mero proxy inverso.
Por verlo gráficamente, el siguiente diagrama muestra la arquitectura tradicional de un sistema ASP.NET Core funcionando sobre IIS. En el modelo out-of-process utilizado hasta ASP.NET Core 2.1, cada petición realizada desde el exterior era capturada por IIS, que a su vez lanzaba una petición HTTP local con los mismos contenidos hacia Kestrel, que era quien la procesaba ejecutando nuestro código. La respuesta generada desde Kestrel era enviada de vuelta a IIS como respuesta a la petición, quien la retornaba al agente de usuario:

En este modelo de funcionamiento, por tanto, cada petición HTTP entrante generaba otra petición HTTP interna que, aunque estuviera dentro de la misma máquina, imponía una penalización importante en el rendimiento de las aplicaciones.
El hosting in-process, aparecido con ASP.NET Core 2.2, cambia las reglas del juego eliminando esas peticiones HTTP internas y los retardos que implicaban, lo que ha posibilitado el espectacular incremento en el rendimiento que su uso ofrece. Ahora, el módulo para IIS ejecuta internamente la aplicación y se comunica con ella de forma directa:

Este es el modo por defecto de los nuevos proyectos ASP.NET Core creados usando las plantillas estándar, algo que podemos claramente ver si echamos un vistazo al archivo
.csproj
de un proyecto recién creado, ya sea desde Visual Studio o desde .NET Core CLI: <PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
</PropertyGroup>
Si tenéis un proyecto ASP.NET Core 2.1 o anterior y lo actualizáis a 2.2, tendréis que añadir el elemento <AspNetCoreHostingModel>
de forma manual para usar este modelo de ejecución.
Sin embargo, estas mejoras espectaculares no son gratis del todo, y creo que es interesante conocer un poco mejor lo que implica asumir este nuevo modo de funcionamiento de nuestras aplicaciones y responder a algunas preguntas que podríamos hacernos por el camino.Por si te lo perdiste...
- Cómo incluir scripts en la página desde vistas parciales ASP.NET Core MVC con DynamicSections
José María Aguilar - 7 Hábitos de personas altamente innovadoras
José María Aguilar
.NET / .NET Core
- Crear y utilizar librerías multiplataforma con C++ y NetCore (Parte 1)
Jorge Turrado - What Was New for .NET Developers in 2018 & the Road Ahead
Damir Arh - C# – Why you should never use the checked keyword – Unless absolutely necessary
John Demetriou - “Stack Walking” in the .NET Runtime
Matt Warren - Writing a language-agnostic Roslyn Analyzer using IOperation
Gérald Barré - WasmWinforms: C# Winforms for Webassembly
Roozbehid - Switch to errors instead of warnings for nullable reference types in C# 8
Jiří Činčura - Weirdness with EF Core 2 (SQLite), .NET Standard, and .NET Framework
Jeremy Clark - C# .NET Core vs Java - Which programs are faster?
The Benchmarks game - COM Object Access and dynamic in .NET Core 2.x
Rick Strahl - C#’s discards don’t need var
Jiří Činčura - Correctly reading encoded text with the StreamReader in .NET
Jeremy Lindsay - .NET Core tooling update for Visual Studio 2019 Preview 2
Phillip Carter - ThreadPool.QueueUserWorkItem has a generic overload (and a new parameter)
Jiří Činčura - Do more with patterns in C# 8.0
Mads Torgersen - The Ultimate List of .NET Dependency Injection Frameworks
Claudio Bernasconi - C# Deadlocks in Depth – Part 2
Michael Shpilt
Blogger invitado

Jorge Turrado
Apasionado de la programación, siempre buscando la manera de mejorar el día a día con el desarrollo de tecnologías .NET. Apasionado de este momento tan cambiante y fabuloso para ser desarrollador C#.¿Y por qué me debería interesar utilizar código nativo si .NET Core ya es lo bastante rápido? Esa es una muy buena pregunta, es cierto que con .NET Core y su filosofía cloud se ha mejorado muchísimo el rendimiento, y se ha modularizado el framework consiguiendo unos resultados muy buenos.
Sin embargo, imagina que tu aplicación web necesita de un rendimiento excelente, por ejemplo, porque necesites enviarle imágenes y tengas que procesarlas en el servidor para leer un OCR o procesar su contenido. En estos casos, cada ciclo cuenta, ya que afecta directamente a la escalabilidad de tu aplicación; no es lo mismo tardar 10 milisegundos que 20, cuando hablas de un gran número de usuarios concurrentes.
El framework nos da la posibilidad de ejecutar código nativo (ya .NET Framework nos daba esa posibilidad hace mucho), pero el código nativo es código compilado directamente para el sistema operativo, y esto hace que una librería de Windows sólo sirva para Windows, lo mismo que si fuese de Linux o MacOS.
Hoy vamos a abordar ese problema, creando librerías nativas multiplataforma, que podamos compilar sin tener que cambiar nada en ellas (lo cual nos permite tener una única librería que mantener) y consumiéndolas desde .NET Core. Por eso, en mi blog FixedBuffer he dejado la primera parte de esta entrada:
Crear y utilizar librerías multiplataforma con C++ y .NET Core (Parte 1)
A partir de aquí, vamos a considerar que ya tenéis vuestra librería nativa compilada, y vamos a centrarnos solo en la parte de C# y .NET Core.
Publicado por José M. Aguilar a las 10:00 a. m.
Etiquetas: c++, colaboraciones, jorgeturrado, netcore
Por si te lo perdiste...
- Redirecciones HTTP 303, 307 y 308: ¿las conoces?
José María Aguilar - 13 Consejos para comentar tu código
José María Aguilar
.NET / .NET Core
- More DI: Unit Testing Async Methods
Jeremy Clark - Migrating from .NET to .NET Standard
Rockford Lhotka - .NET Standard and Multi-targeting
Corrado Cavalli - Monitoring GC and memory allocations with .NET Core 2.2 and Application Insights
Stefán Jökull Sigurðarson - JSON Web Encryption (JWE) in .NET Core
Scott Brady - System.Data in .NET Core 3.0
Jonathan Allen - Interpolated verbatim string in C# 8
Jiří Činčura - Delegate, predicate, Action, Func, métodos anónimos, explicados para mortales
Leo Micheloni - Stopping Garbage Collection in .NET Core 3.0 (part I)
Luca Bolognese - Performance Tuning for .NET Core
Reuben Bond - Managed pointers in .NET
Konrad Kokosa - Code Contracts: A Technique to Cut Down on Bugs
Carlos Schults - When Will JustMock Support .NET Core? Right Now!
Mihail Vladov - Using Background Intelligent Transfer Service (BITS) from .NET
Peter Smith - C# 8: Type Inference for the New Keyword & Caller Expression Attribute for Assertions and Automated Testing & Generic Attributes
Jonathan Allen - C# Deadlocks in Depth - Part 1
Michael Shpilt
_ViewImports.cshtml
y _ViewStart.cshtml
se emplean para introducir directivas y código de inicialización para todas las vistas o páginas que se encuentren por debajo en la estructura de carpetas del proyecto.Es decir, si el archivo
_ViewImports.cshtml
se encuentra en la carpeta /Views
, todas las vistas que hay por debajo heredarán las directivas que hayamos especificado en su interior, de la misma forma que /Pages/_ViewImports.cshtml
afectara a las páginas presentes en la carpeta /Pages
y descendientes.Pues bien, hace unos días, un alumno del curso de ASP.NET Core en CampusMVP (que, por cierto, ha sido recientemente actualizado a la versión 2.2 del framework) planteaba una duda sobre un escenario algo más complejo. Si una aplicación tenía vistas en la carpeta
/Views
, también tenía vistas en áreas (carpeta /Areas
), e incluso pudiera tener algunas páginas Razor en /Pages
, la pregunta era si existía algún mecanismo para hacer que todas las vistas o páginas definidas en dichas carpetas compartieran directivas (como using
o importaciones de tag helpers) sin tener que duplicar este código en sus respectivos _ViewImports.cshtml
para cada una de ellas.A priori pensé que quizás el planteamiento sería retocar ligeramente el motor de vistas, pero, tras estudiarlo un rato, vi que el tema era mucho más sencillo :)
Por si te lo perdiste...
- Extendiendo claims de usuarios en ASP.NET Core
José María Aguilar - Problemas al comentar el código fuente
José María Aguilar
.NET / .NET Core
- .NET Core January 2019 Updates – 2.1.7 and 2.2.1
Lee Coward - Codez: A Random String Generator and Why I Wrote It
Khalid Abuhakmeh - Rendering Markdown to HTML and Parsing YAML Front Matter in C#
Mark Heath - Do we need JVM’s PhantomReference in .NET?
Konrad Kokosa - Implementing Phantom Reference in C#
Oren Eini - Implementing Java ReferenceQueue and PhantomReference in C#
Kévin Gosse - Collectible assemblies in .NET Core 3.0 | StrathWeb. A free flowing web tech monologue.
Filip Woj - Announcing ML.NET 0.9 – Machine Learning for .NET
César de la Torre - Profiling Concurrent .NET Code with BenchmarkDotNet and visualizing it with Concurrency Visualizer
Adam Sitnik - Deep-dive into .NET Core primitives, part 3: runtimeconfig.json in depth
Nate McMaster
Por si te lo perdiste...
- Renderizar una vista Razor a un string en ASP.NET Core MVC
José María Aguilar - Top posts 2017 en Variable not found
José María Aguilar
.NET / .NET Core
- Generate automatically async/await code from sync code with Roslyn
Alexandre Mutel - Background jobs in ASP.NET Core made easy with Hangfire
Matthew D. Groves - How to parse a high rate stream of data with low memory allocation
Riccardo Terrell - Comparing RestSharp and Flurl.Http while consuming a web service in .NET Core
Jeremy Lindsay - Less commonly used C# operators
Damir Arh - SOLID Principles in C# - Open Closed Principle
Marinko Spasojevic - Build your first .NET Core 3.0 application in Linux
Anuraj Parameswaran - Implement Observer Pattern in .NET (3 Techniques)
Chinmoy Mohanty - String Interpolation Functions vs. string.Format Constants
Scott Hannen - Using Polly and Flurl to improve your website
Jeremy Lindsay - Image Classification Using Keras
James McCaffrey - Accessibility of nested classes
Eric Lippert - Find, Fix, and Avoid Memory Leaks in C# .NET: 8 Best Practices
Michael Shpilt

También, como no podía ser de otra forma, aprovecho también para desearos a todos un año 2019 lleno de alegrías tanto en el terreno personal como en el profesional, deseo que podéis considerar extensible para a todos los que os rodean y os importan :)
Y dicho esto, vamos al tema...

Por ejemplo, en las consultorías técnicas que realizo en empresas es frecuente encontrar equipos de trabajo en los que aún no está generalizado el uso de construcciones tan útiles como el null coalescing operator (
fullName ?? "Anonymous"
), safe navigation operator (person?.Address?.Street
), el at object operator (Address@person
), o características tan potentes como las funciones locales, interpolación de cadenas, tuplas o muchas otras.Sin embargo, creo que el rey de los desconocidos es el operador virgulilla "~" de C#. Introducido con C#7 es probablemente uno de los operadores menos utilizados y, sin embargo, de los más potentes ofrecidos por el lenguaje.
Nota de traducción: el nombre original del operador es "tilde operator", y como he encontrado poca literatura al respecto en nuestro idioma, me he tomado la libertad de traducirlo como operador virgulilla (¡sí, esa palabra existe!). También, en entornos más informales lo encontraréis con el nombre "wormy operator" (operador gusanillo) o como "soft similarity operator" (que podríamos traducir como operador de similitud relajada).

Y de paso, aprovecho este momento para desearos a todos unas felices fiestas y un grandioso 2019 en todos los ámbitos.
Por si te lo perdiste...
- Xmas Tree scan, el escaneo de puertos navideño
José María Aguilar - Constantes string multilínea en C#
José María Aguilar
.NET / .NET Core
- .NET Core - What's Coming in .NET Core 3.0
Scott Hunter - Composing Honest Methods in C#
Yacoub Massad - Comparaciones en C#
Eduard Tomás - ClosedXML, una manera fácil de dar formato a nuestros .xlsx
Jorge Turrado - VB.NET Hits High in Programming Language Popularity Index
David Ramel - Enable repeatable package restores using a lock file
Anand Gaurav - Garbage Collection in C# (.NET Framework and .NET Core)
Damir Arh - Writing a Roslyn analyzer
Gérald Barré - The Lazy applicative functor
Mark Seemann - Interesting uses of tuple deconstruction
Nigel Sampson - C# All The Things
David Pine - Presenting HttpTracer Library
Daniel Causer - How to Remove Application Insights
Matt Watson - C# Features: An Exhaustive List of the Best Ones
Carlos Schults - Updating Westwind.AspnetCore.Markdown with Markdown from Files and URLs
Rick Strahl - Top .NET Tutorials in 2018
David Ramel
Por ejemplo, echando un vistazo al siguiente controlador podemos ver claramente una violación del Principio de Responsabilidad Única (SRP) en un controlador que conoce demasiados detalles sobre la forma de proceder al registrar un pedido:
public class OrderController: Controller
{
private readonly IOrderServices _orderServices;
[...] // Other private members
public OrderController(IOrderServices orderServices, IUserServices userServices,
IMailingService mailingServices, ISmsServices smsServices,
IPdfGenerator pdfGenerator, IMapper mapper
)
{
_orderServices = orderServices;
_userServices = userServices;
[...] // Other assignments...
}
[HttpPost]
public Task<IActionResult> Submit(OrderViewModel orderViewModel)
{
if(!ModelState.IsValid)
{
return View(orderViewModel);
}
var orderDto = _mapper.Map<OrderDto>(orderViewModel);
var orderResult = await _orderServices.AddAsync(orderDto);
if(!orderResult.Success)
{
return RedirecToAction("OrderError", new { error = orderResult.Error }));
}
var userPreferences = await _userServices.GetNotificationPreferencesAsync(CurrentUserId);
var pdfUrl = await _pdfGenerator.GenerateOrderAsync(orderResult.Details);
if(userPreferences.NotificationMode == NotificationMode.Sms)
{
await _smsServices.NotifyNewOrderAsync(orderResult.Details, pdfUrl);
}
else
{
await _mailingServices.NotifyNewOrderAsync(orderResult.Details);
}
return RedirectToAction("ThankYou", new { id = orderResult.Details.OrderId } );
}
...
}
En dicho post comentaba también algunas cosas que podíamos hacer para solucionar el problema, así como una recomendación de lo que no debíamos hacer: disimular dependencias instanciando directamente componentes o utilizando otros "sabores" de inyección que hicieran menos evidente la relación de nuestra clase con otras de las que depende.Pues bien, como hoy estamos algo rebeldes, vamos a ver las técnicas que nos permitirían hacerlo cuando sea necesario o, dicho de otra forma, qué alternativas tenemos para usar dependencias desde los controladores sin que estas sean suministradas mediante inyección en su constructor.
Precaución: estas técnicas son consideradas antipatrones o, como mínimo, code smells en la mayoría de los escenarios, así que usadlas poco, con precaución y siempre con conocimiento de causa ;)
Por si te lo perdiste...
- Leyes epónimas relacionadas con el desarrollo de software (y II)
José María Aguilar - 10 razones por las que tu blog te ayuda a encontrar empleo
José María Aguilar
.NET / .NET Core
- Seven reasons that Roslyn-based Code Analysers are awesome
Tom Wright - A Simple Look at .NET Memory Model
James M. Curran - Why is string.GetHashCode() different each time I run my program in .NET Core?
Andrew Lock - Six Opinionated Tips to be a Better .NET Developer
Isaac Levin - Writing xUnit Tests in .NET Core & Providing Constant Context for .NET Core Tests
Peter Vogel - Support for Value Objects in C#
Steve Smith - Explicit interface implementation
Ed Freeman - Announcing .NET Framework 4.8 Early Access Build 3707
Namrata Karnam - Exploring the .NET Core Runtime (in which I set myself a challenge)
Matt Warren
En todos los casos son revisiones pequeñas y que no rompen nada de lo anterior, pero en cada uno de estos productos se han introducido mejoras que vale la pena conocer, por lo que, antes que nada, os recomiendo que echéis un vistazo a los artículos anteriores, que son los anuncios oficiales.
En este post vamos a ver rápidamente las novedades más destacables de ASP.NET Core 2.2.