Tema: csharp
-
Convenciones de inyección de dependencias en .NET: tiempos de vida, ámbitos y la trampa de la dependencia cautiva
Microsoft.Extensions.DependencyInjection registra servicios en un IServiceCollection con tiempo de vida transient, scoped o singleton, y los inyecta mediante constructores públicos; las reglas documentadas son nunca inyectar un servicio scoped en un singleton, dejar que el contenedor libere lo que creó, evitar llamadas de tipo localizador de servicios, y validar los ámbitos para que las dependencias cautivas fallen al arrancar en lugar de filtrar estado entre solicitudes.
-
Escribir una prueba unitaria en JUnit 5 y xUnit.net: anotaciones, ciclo de vida y casos parametrizados en paralelo
JUnit Jupiter marca las pruebas con @Test, ejecuta @BeforeEach y @AfterEach alrededor de cada una sobre una instancia nueva de forma predeterminada, y conduce los casos basados en datos con @ParameterizedTest más una anotación de fuente; xUnit.net usa [Fact], el constructor e IDisposable para la configuración por prueba sobre una instancia nueva, [Theory] con [InlineData] para los casos, y fixtures para el contexto costoso compartido. Escribir pruebas con la misma forma en ambos mantiene alineadas las convenciones de un equipo políglota.
-
Trampas de async/await en C#: sync-over-async, async void y ConfigureAwait
Los errores clásicos en el código asíncrono de C# son bloquear sobre un Task con .Result, .Wait() o GetAwaiter().GetResult() (interbloqueos bajo un SynchronizationContext de un solo hilo, agotamiento del grupo de hilos en servidores), los métodos async void cuyas excepciones no se pueden capturar, y colocar mal ConfigureAwait(false), que pertenece a las bibliotecas de propósito general y no al código de la aplicación.
-
Fijar dependencias de NuGet: PackageReference, gestión central de paquetes y packages.lock.json
NuGet resuelve en cada restore la versión mínima aplicable de cada paquete, de modo que el resultado puede variar si aparecen versiones nuevas o rangos flotantes. Para un build repetible, se declaran las versiones una sola vez en Directory.Packages.props, se activa RestorePackagesWithLockFile para que packages.lock.json registre la clausura completa, se hace commit del archivo de bloqueo en las aplicaciones y se restaura con --locked-mode en CI.
-
Tipos de referencia anulables en C#: un contrato en tiempo de compilación, no una comprobación en ejecución
Con <Nullable>enable</Nullable>, el compilador de C# trata string como no anulable y string? como anulable, sigue el estado de nulidad de cada expresión y advierte de las incoherencias; en ejecución no cambia nada, porque string y string? son el mismo tipo. El operador de supresión de nulos (null-forgiving) ! y los atributos de análisis de nulabilidad ([NotNullWhen], [MemberNotNull]) sirven para indicar al compilador lo que no puede deducir por sí mismo.
Legible por máquina: JSON