Skip to content

Fix unkeyed DependsOn ServiceKey resolution (#112) - #119

Merged
AGiorgetti merged 3 commits into
developfrom
codex/fix-112-unkeyed-servicekey
Oct 9, 2026
Merged

AGiorgetti merged 3 commits into
developfrom
codex/fix-112-unkeyed-servicekey

Conversation

@AGiorgetti

Copy link
Copy Markdown
Contributor

Unkeyed or explicit-null-key DependsOn registrations treated [ServiceKey] as contextual injection even without an effective key. This injected null into reference-type parameters and rejected registered value-type parameters. Native Microsoft DI resolves those parameters from ordinary registrations or optional defaults.

Fixes #112.

Constructor selection and argument resolution now inject [ServiceKey] only when the effective key is non-null. Named value/key overrides remain first; non-null keys retain their existing type checks. Ordinary registered null results, missing required dependencies, optional defaults and factory exceptions keep their established behavior. This uses the existing resolution path and adds no reflection. The README and vNext changelog describe the corrected contract.

Regression tests were committed before the implementation. The 240 new cases per target compare native DI with mapped activation through plain BuildServiceProvider(), Mammoth's snapshot provider and its diagnostic provider, covering string/object/int/nullable-int parameters, unkeyed/null-key contexts, registrations/defaults/null results/exceptions, lifetimes, named overrides and genuine non-null keys. Before the fix, 138 failed and 102 passed on every target. Four older fixture cases assumed the faulty null-injection behavior; their corrected native expectations also failed before the fix (with two keyed controls passing).

Verification on Windows:

  • Restore and Release solution build with ContinuousIntegrationBuild=True: passed; zero errors, zero compiler/analyzer warnings. Two existing package-support warnings state that Microsoft.Extensions.Telemetry.Abstractions 10.0.0 and Microsoft.Extensions.Diagnostics.Testing 10.0.0 do not claim net472 support.
  • Full suite: 2,497 passed, zero failed/skipped on each of net472, net8.0, net9.0 and net10.0 (9,988 total). The net472 assembly ran under .NET Framework 4.8.9345.0.
  • Native cache probes using Microsoft DI 10.0.0: passed on all four targets, each with 100 interleaved enumerations after observed native compilation.
  • Whitespace check: passed.

Exact final-commit CI evidence will be added in a PR discussion comment after GitHub Actions completes. Draft for review; no merge, release or publication actions requested.

Co-authored-by: Codex codex@openai.com

AGiorgetti and others added 3 commits October 9, 2026 10:21
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>

Copy link
Copy Markdown
Contributor Author

Implemented in draft PR #119: #119

The defect came from treating [ServiceKey] as contextual injection when the effective key was null. Constructor selection could reject a registered int parameter, while argument resolution silently supplied null for string/object parameters. Both paths now require a non-null effective key before injecting it. Without one, the existing ordinary-registration/default path applies, matching native Microsoft DI. For example, a registered int value 42 is now supplied to an unkeyed mapped constructor even when its key parameter has [ServiceKey].

Named value/key overrides still run first; genuine non-null keys retain type validation. Registered null factory results do not become optional defaults, missing required registrations fail before unrelated activation, and factory exceptions pass through unchanged. The fix adds no reflection and updates the README and vNext changelog.

Tests were committed first. The 240 new cases per target produced 138 failures and 102 passing controls before the fix on all four targets. Four older cases asserted the defect's null-injection behavior; corrected native expectations also failed before the fix, with their two keyed controls passing.

Verification for final commit e8fc2422cf02dffb60361d12df848361bbb484df:

  • Local Windows restore and Release CI-style build passed.
  • Local and Windows CI full suites each passed 2,497 tests on net472/net8.0/net9.0/net10.0: 9,988 passed, zero failed/skipped per full run.
  • Local and CI native DI 10.0.0 cache probes passed on all four targets, each with 100 interleaved enumerations after observed compilation.
  • Whitespace check passed. No applicable checks were unavailable.
  • The build has only the two existing net472 support warnings from Microsoft.Extensions.Telemetry.Abstractions and Microsoft.Extensions.Diagnostics.Testing 10.0.0, with no compiler/analyzer warnings or errors.
  • Exact-commit CI: https://github.com/PrimordialCode/Mammoth.Extensions.DependencyInjection/actions/runs/37905150220 (success). Pack and Publish were skipped.

Paused for review. This is the last bug in the original #106–#112 list; after review and merge, a release-validation checkpoint is appropriate. No release actions were taken.

@AGiorgetti
AGiorgetti marked this pull request as ready for review October 9, 2026 08:35
@AGiorgetti
AGiorgetti merged commit b531864 into develop Oct 9, 2026
2 checks passed
@AGiorgetti
AGiorgetti deleted the codex/fix-112-unkeyed-servicekey branch October 9, 2026 08:37
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.

Unkeyed DependsOn injects null or rejects registered ServiceKey parameter types

1 participant