Tema: csharp
-
Convenções de injeção de dependência no .NET: tempos de vida, escopos e a armadilha da dependência capturada
O Microsoft.Extensions.DependencyInjection registra serviços em um IServiceCollection com tempo de vida transient, scoped ou singleton e os injeta por construtores públicos. As regras documentadas: nunca injetar um serviço scoped em um singleton, deixar o contêiner descartar o que ele criou, evitar chamadas de service locator e validar os escopos para que dependências capturadas falhem na inicialização em vez de vazarem estado entre requisições.
-
Como escrever um teste unitário em JUnit 5 e xUnit.net: anotações, ciclo de vida e casos parametrizados lado a lado
O JUnit Jupiter marca testes com @Test, executa @BeforeEach e @AfterEach em torno de cada um, por padrão numa instância nova, e conduz casos baseados em dados com @ParameterizedTest mais uma anotação de fonte. O xUnit.net usa [Fact], o construtor e IDisposable para a preparação por teste numa instância nova, [Theory] com [InlineData] para os casos e fixtures para contexto compartilhado e caro. Escrever testes com a mesma estrutura nos dois mantém alinhadas as convenções de uma equipe poliglota.
-
Armadilhas do async/await em C#: sync-over-async, async void e ConfigureAwait
Os erros clássicos em código assíncrono C# são bloquear uma Task com .Result, .Wait() ou GetAwaiter().GetResult() (deadlocks com um SynchronizationContext de thread única, esgotamento do thread pool em servidores), métodos async void cujas exceções não podem ser capturadas e o uso incorreto de ConfigureAwait(false), que pertence a bibliotecas de uso geral e não ao código de aplicação.
-
Fixar dependências NuGet: PackageReference, gerenciamento central de pacotes e packages.lock.json
O NuGet resolve, no momento do restore, a menor versão aplicável de cada pacote, o que pode causar deriva quando surgem novas versões ou intervalos flutuantes; um build repetível declara as versões uma única vez em Directory.Packages.props, ativa RestorePackagesWithLockFile para que o packages.lock.json registre o fecho completo, versiona o arquivo de lock nas aplicações e restaura com --locked-mode no CI.
-
Tipos de referência anuláveis em C#: um contrato em tempo de compilação, não uma verificação em tempo de execução
Com <Nullable>enable</Nullable>, o compilador C# trata string como não anulável e string? como anulável, rastreia o estado de nulidade de cada expressão e emite avisos quando há incompatibilidade; em tempo de execução nada muda, pois string e string? são o mesmo tipo. O operador de tolerância a nulo ! e os atributos de análise de nulidade ([NotNullWhen], [MemberNotNull]) servem para informar ao compilador o que ele não consegue inferir.
Legível por máquina: JSON