Sujet : dotnet
-
Conventions d'injection de dépendances en .NET : durées de vie, portées et piège de la dépendance captive
Microsoft.Extensions.DependencyInjection enregistre les services dans un IServiceCollection avec une durée de vie transient, scoped ou singleton et les injecte via des constructeurs publics ; les règles documentées sont de ne jamais injecter un service scoped dans un singleton, de laisser le conteneur libérer ce qu'il a créé, d'éviter les appels de type localisateur de services et de valider les portées pour que les dépendances captives provoquent un échec au démarrage plutôt qu'un partage d'état indu entre requêtes.
-
Quels signaux d'observabilité un service JVM ou .NET devrait-il émettre par défaut, et à quel coût ?
Question ouverte : les deux environnements d'exécution embarquent une télémétrie native (Flight Recorder et la journalisation du GC sur la JVM ; les compteurs EventPipe et dotnet-trace sur .NET) et disposent tous deux d'une auto-instrumentation OpenTelemetry, mais il existe peu de preuves partagées sur lesquels de ces signaux devraient être activés en permanence en production, ce qu'ils coûtent, et lesquels ont réellement raccourci des incidents.
-
Écrire un test unitaire en JUnit 5 et xUnit.net : annotations, cycle de vie et cas paramétrés côte à côte
JUnit Jupiter marque les tests avec @Test, exécute @BeforeEach et @AfterEach autour de chacun sur une instance fraîche par défaut, et pilote les cas pilotés par les données avec @ParameterizedTest plus une annotation de source ; xUnit.net utilise [Fact], le constructeur et IDisposable pour l'initialisation par test sur une instance fraîche, [Theory] avec [InlineData] pour les cas, et des fixtures pour un contexte coûteux partagé. Écrire des tests de même forme dans les deux garde alignées les conventions d'une équipe polyglotte.
-
Pièges d'async/await en C# : sync-over-async, async void et ConfigureAwait
Les erreurs classiques du code asynchrone en C# consistent à bloquer sur une Task avec .Result, .Wait() ou GetAwaiter().GetResult() (blocages sous un SynchronizationContext monothread, famine du thread pool sur les serveurs), à écrire des méthodes async void dont les exceptions ne peuvent pas être interceptées, et à mal placer ConfigureAwait(false), qui a sa place dans les bibliothèques génériques et non dans le code applicatif.
-
Figer les dépendances NuGet : PackageReference, gestion centralisée des paquets et packages.lock.json
NuGet résout la version applicable la plus basse de chaque paquet au moment de la restauration, si bien qu'une restauration peut dériver quand de nouvelles versions ou des plages flottantes apparaissent ; une build reproductible déclare les versions une seule fois dans Directory.Packages.props, active RestorePackagesWithLockFile pour que packages.lock.json enregistre la fermeture transitive complète, versionne le fichier de verrouillage pour les applications, et restaure avec --locked-mode en intégration continue.
-
Les types de référence nullables en C# : un contrat de compilation, pas une vérification à l'exécution
Avec <Nullable>enable</Nullable>, le compilateur C# traite string comme non nullable et string? comme nullable, suit l'état de nullité de chaque expression et émet un avertissement en cas d'incohérence ; rien ne change à l'exécution, string et string? sont le même type, et l'opérateur de tolérance de nullité ! ainsi que les attributs d'analyse de nullité ([NotNullWhen], [MemberNotNull]) servent à indiquer au compilateur ce qu'il ne peut pas déduire.
Lisible par machine : JSON