テーマ: csharp
-
.NETの依存性注入の慣習: ライフタイム、スコープ、captive dependencyの罠
Microsoft.Extensions.DependencyInjectionは、`IServiceCollection`上にtransient・scoped・singletonのいずれかのライフタイムでサービスを登録し、公開コンストラクタを通じてそれらを注入する。文書化されたルールは、scopedなサービスをsingletonに注入しないこと、コンテナが生成したものはコンテナ自身に破棄させること、サービスロケーター的な呼び出しを避けること、そしてcaptive dependencyがリクエストをまたいで状態を漏らすのではなく起動時に失敗するようスコープの検証を行うことである。
-
JUnit 5 と xUnit.net で単体テストを書く:注釈、ライフサイクル、パラメーター化ケースの比較
JUnit Jupiter は @Test でテストを示し、既定では新しいインスタンス上の各テストの前後に @BeforeEach と @AfterEach を実行し、@ParameterizedTest とソース注釈でデータ駆動のケースを扱う。xUnit.net は [Fact]、コンストラクター、IDisposable で新しいインスタンス上のテストごとの準備と後始末を行い、[Theory] と [InlineData] でケースを、フィクスチャで高コストの共有コンテキストを扱う。両方で同じ形のテストを書くと、多言語チームの慣習をそろえられる。
-
C# async/await pitfalls: sync-over-async, async void and ConfigureAwait
The classic mistakes in C# asynchronous code are blocking on a Task with .Result, .Wait() or GetAwaiter().GetResult() (deadlocks under a single-threaded SynchronizationContext, thread-pool starvation on servers), async void methods whose exceptions cannot be caught, and misplacing ConfigureAwait(false), which belongs in general-purpose libraries and not in application code.
-
Pinning NuGet dependencies: PackageReference, central package management and packages.lock.json
NuGet resolves the lowest applicable version of each package at restore time, so a restore can drift when new versions or floating ranges appear; a repeatable build declares versions once in Directory.Packages.props, enables RestorePackagesWithLockFile so packages.lock.json records the full closure, commits the lock file for applications, and restores with --locked-mode in CI.
-
C# の null 許容参照型:実行時の検査ではなく、コンパイル時の契約
<Nullable>enable</Nullable> を設定すると、C# コンパイラーは string を null 非許容、string? を null 許容として扱い、各式の null 状態を追跡して不一致を警告する。実行時の変化はなく、string と string? は同じ型である。null 免除演算子 ! と null 許容性分析属性([NotNullWhen]、[MemberNotNull])は、コンパイラーが推論できないことを伝えるために使う。
機械可読: JSON