Skip to content

Add DP066 and Autofac coverage to CaptiveDependencyAnalyzer#222

Merged
Skymly merged 1 commit into
mainfrom
feature/dp066-factory-delegate-captive-dependency
Jul 8, 2026
Merged

Add DP066 and Autofac coverage to CaptiveDependencyAnalyzer#222
Skymly merged 1 commit into
mainfrom
feature/dp066-factory-delegate-captive-dependency

Conversation

@Skymly

@Skymly Skymly commented Jul 8, 2026

Copy link
Copy Markdown
Owner

Summary

Singleton lifecycle diagnostics P1 (RFC, ADR-008, Plan) — Analyzers module only.

  • Autofac coverage for DP062: CaptiveDependencyAnalyzer now collects Autofac registrations (RegisterType<T>() / RegisterType(typeof(T)) with fluent lifetime chain resolution — SingleInstance, InstancePerLifetimeScope, default InstancePerDependency — and Register(c => ...) delegates). Autofac methods are matched by containing-namespace symbol check; the analyzer takes no Autofac package reference.
  • New DP066 (Warning) — factory delegate captive dependency: reported when a Singleton factory delegate (MSDI AddSingleton<T>(sp => ...) or Autofac Register(...).SingleInstance()) directly resolves a Scoped/Transient service via GetRequiredService / GetService / Resolve. Only direct calls in the delegate body are detected (documented limitation).
  • DP062 gap fix: MSDI factory and instance registrations now feed the lifetime map, so a Singleton constructor-depending on a factory-registered Scoped/Transient service reports DP062 (previously missed entirely).
  • RS2002 suppressed alongside the existing RS2003 in the Analyzers project: release tracking cannot resolve compile-linked descriptor IDs, so unshipped entries false-positive.
  • Docs sync: AGENTS.md diagnostics table, ROADMAP next available ID (DP067, DP067–DP071 reserved by the RFC), CHANGELOG, plan P1 status.

Test plan

  • 11 new Verify snapshot tests: Autofac constructor captive (explicit scoped, default transient, fluent chain with intermediate As<T>(), negative), DP066 (MSDI GetRequiredService/GetService, Autofac Resolve, negatives incl. non-container Resolve method), DP062 via scoped factory registration
  • Autofac added as a test-only dependency of Analyzers.Tests
  • Full Ci target (Release): 0 warnings, 657 tests passing

Singleton lifecycle diagnostics P1 (RFC: SingletonLifecycleDiagnostics,
ADR-008):

- Collect Autofac registrations (RegisterType + fluent lifetime chain,
  Register delegate) by symbol-name matching with no Autofac package
  reference, reusing DP062 constructor analysis.
- New DP066 (Warning): a Singleton factory delegate (MSDI AddSingleton
  factory or Autofac Register(...).SingleInstance()) directly resolves
  a Scoped/Transient service via GetRequiredService/GetService/Resolve.
- MSDI factory and instance registrations now feed the lifetime map,
  so Singletons constructor-depending on factory-registered Scoped or
  Transient services report DP062 (previously missed).
- Suppress RS2002 alongside RS2003: release tracking cannot resolve
  compile-linked descriptor IDs, so unshipped entries false-positive.
- 11 new Verify snapshot tests (Autofac is a test-only dependency of
  Analyzers.Tests); sync AGENTS.md diagnostics table, ROADMAP next
  available ID (DP067), CHANGELOG, and plan P1 status.

@Skymly Skymly left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CI is green (build-test, pack, samples all passed).

Scope & alignment

  • P1 matches ADR-008 / the plan: Autofac registration collection via symbol-name matching (no analyzer package reference), DP066 for Singleton factory delegates, and the DP062 lifetime-map gap fix for MSDI factory/instance registrations.
  • Module boundary is respected (Analyzers + Diagnostics + tests/docs only).

Implementation notes

  • SkipConstructorAnalysis cleanly separates lifetime-map participation from constructor analysis for factory/instance registrations.
  • SemanticModel captured at collection time for DP066 avoids RS1030 at compilation end.
  • Autofac fluent-chain lifetime resolution walks intermediate calls (As<T>(), etc.) correctly.
  • RS2002 suppression alongside RS2003 is justified given compile-linked descriptors; AnalyzerReleases.Unshipped.md is updated for DP066.

Tests

  • 11 Verify snapshots cover positive/negative paths for Autofac DP062, MSDI/Autofac DP066, and the scoped-factory DP062 regression.
  • System.ComponentModel reference added for IServiceProvider in test compilations — good catch.

Follow-ups (non-blocking, already in RFC/plan)

  • P2a/P2b/P3 remain open per the plan.
  • Factory-delegate analysis limitation (direct GetRequiredService/GetService/Resolve only) should land in a Design Doc when P1 merges.

LGTM to merge from my side.

@Skymly Skymly merged commit 2d71b78 into main Jul 8, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant