Upgrading
Move to 3.10 without guessing why findings changed
Diagnostic IDs and default severities are stable. Releases can still remove findings when a rule is narrowed to avoid a proven false positive.
Upgrading
The analyzer package follows SemVer. Diagnostic IDs, default severities, and code-fix behavior are the stable contract; releases can still remove findings when a rule is narrowed to avoid a proven false positive. This page records the behavior changes that can move a build from green to clean, or from noisy to quiet.
3.9.x
3.9.0 — DI001 and DI019 scope wrappers
canonical if (scope is IAsyncDisposable alias) await alias.DisposeAsync(); else scope.Dispose(); shape plus scopes stored in a field and disposed by the owning type.
the singleton's own or inherited provider properties, known host properties, and real scope providers qualify.
- DI001 treats a scope wrapped in a directly returned object as caller-owned, and recognizes the
- DI019 no longer treats a custom wrapper's
ServiceProviderproperty as the root provider. Only
If a previously reported finding disappeared, check whether the scope is now proven caller-owned or the provider is a custom wrapper. If the new result is wrong, open a false-negative report.
3.10.1 — test and mutation hardening
assignability, constructor selection, and keyed-service extraction.
changes.
- The shared-resolution-helper mutation gate rises from 80.00% to 94.92%, with direct tests for
- The nullable assignability check is expressed as explicit guards. No analyzer or scanner behavior
3.10.0 — scanner UX and maintenance
second mutation shard.
di-scan --fixapplies safe code fixes withdotnet format.di-scan --update-baseline <file>writes a text baseline that--baselinereads back.- Windows/macOS scanner CI, false-positive/negative issue forms, Dependabot, CODEOWNERS, and a
- No analyzer behavior changes.
3.9.1–3.9.3 — packaging and discoverability
No analyzer behavior changes. These releases shipped the concise NuGet README, the scanner docs page, NuGet metadata, and GitHub topics.
3.8.0 — scanner, profiles, and test-code suppression
directories, type/namespace names, base types, and test attributes. Findings in test projects disappear by design. If a production project is named or laid out like a test project, override the suppressor with a narrow #pragma or an .editorconfig severity.
DbContextOptions<TContext> as satisfying a non-generic DbContextOptions dependency.
docs/rules/.
- Test code is suppressed using the HttpClient analyzer conventions: test project names,
- DI001 recognizes conditional async disposal and field-owned scopes.
- DI006 skips custom, stateless
IServiceProvidernull-object providers. - DI015 skips type parameters and closed generics containing them, and treats any registered
- The package now ships starter profiles under
profiles/and one page per rule under
Keeping the previous behavior
Pin the last version that matched your policy:
<PackageReference Include="DependencyInjection.Lifetime.Analyzers" Version="3.7.8">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Or keep the newer analyzer and lower one rule:
[*.cs]
dotnet_diagnostic.DI015.severity = none
For DI015's framework-service assumption, use the documented option:
[*.cs]
dotnet_code_quality.DI015.assume_framework_services_registered = false
Regenerating a scanner baseline
When a reviewed behavior change intentionally removes findings, regenerate only the affected baseline and review the diff:
di-scan ./MyApp.slnx --update-baseline di.baseline
git diff di.baseline
For the pinned repository corpus:
pwsh ./scripts/Invoke-ScanRegression.ps1 -UpdateBaselines
git diff tests/scan-corpus/baselines
Never hand-edit a baseline to make a failing scan pass.
Cross-project composition
DI015 analyzes one compilation at a time. A library cannot see a registration added by a downstream web project, so a partial composition root can report a missing dependency that the application actually registers. Run the scanner against the composition-root project, or lower DI015 for the library, and record the target as a partial composition root.
Reporting a change
Use the dedicated false-positive or false-negative form. Include the rule ID, package or scanner version, the smallest repro, and the expected lifetime or activation result.