Skip to content

Fix mapped key attribute precedence (#122) - #125

Merged
AGiorgetti merged 2 commits into
developfrom
codex/fix-122-key-attribute-order
Oct 9, 2026
Merged

AGiorgetti merged 2 commits into
developfrom
codex/fix-122-key-attribute-order

Conversation

@AGiorgetti

@AGiorgetti AGiorgetti commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Adding an unrelated nonempty DependsOn map changed [FromKeyedServices("fixed"), ServiceKey] from the explicitly keyed dependency to the owning service key. Preserve native DI's attribute order for untouched parameters, while keeping named overrides first.

Fixes #122. Parameter metadata now caches whether FromKeyedServices precedes ServiceKey. A shared predicate selects the first effective non-null key binding during both constructor selection and argument resolution, including inherited/null keys. Contextual decorators reuse the corrected metadata. The change adds no service resolutions, graph validator or private DI API access; attribute inspection remains in the existing weak metadata cache. README and the vNext changelog document the behavior.

Verification on Windows with Microsoft DI 10.0.0:

  • Regression tests committed before the fix: 24 failed and 138 controls passed on each of net472/net8.0/net9.0/net10.0. All 162 new cases now pass on every target.
  • Coverage includes both attribute orders, keyed/unkeyed/null contexts, mismatched owning-key types, registered/missing/null/throwing dependencies, required/optional parameters, unused/unrelated maps, named value/key overrides, effective inherited/null lookups, lifetimes, repeated scopes/resolution, dependency activation counts, and native/snapshot/diagnostic providers and contextual decorators.
  • The standalone issue probe reproduces dependency versus blue on both current develop and published 0.8.0 across all four targets.
  • Full restore and Release solution build with ContinuousIntegrationBuild=True passed. An initial build hit reused-worker access errors; a fresh-worker build passed. Initial fixture/nullable warnings were corrected. Final build: zero errors or compiler/analyzer warnings, with only the two existing net472 package-support warnings from Microsoft.Extensions.Telemetry.Abstractions and Microsoft.Extensions.Diagnostics.Testing 10.0.0.
  • Full suite: 2,740 passed, zero failed/skipped per target; 10,960 total. net472 executed under .NET Framework 4.8.9345.0; modern runtimes were 8.0.31, 9.0.20 and 10.0.12.
  • Native DI hot-cache probes passed on all four targets, each with 100 interleaved enumerations after observed native compilation.
  • Whitespace check passed. No applicable final check was unavailable.

CI for the exact final commit 94af8ba1eaadedb39a4075ea8c9eb5dbe547541f passed: run 37932581363. Windows restore/build, all 10,960 tests and the four native DI hot-cache probes passed; only the same two net472 package-support warnings appeared. Pack and Publish were skipped.

Draft for review; stop here until explicit continuation. #121 and PR #124 remain on hold. After review/merge, a release-validation checkpoint should explicitly acknowledge deferred #121; this PR does not establish full native graph-planning parity. No release actions are included.

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

AGiorgetti and others added 2 commits October 9, 2026 14:39
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
@AGiorgetti

Copy link
Copy Markdown
Contributor Author

Implemented in draft PR #125, against current develop 571df307caf6311b1ec02f63c5134905c3f6b85e. Final feature commit: 94af8ba1eaadedb39a4075ea8c9eb5dbe547541f.

The mapped activator retained both key attributes as independent flags and always considered ServiceKey first. Thus [FromKeyedServices("fixed"), ServiceKey] injected "blue" instead of the registered "dependency" when a nonempty map left that parameter untouched. Native DI processes the attributes in metadata order.

The fix caches one additional metadata flag describing the attribute order. A shared predicate applies that order consistently during constructor selection and argument resolution. A preceding FromKeyedServices binding wins when its effective key is non-null, even when its dependency is missing; normal availability/default rules then apply. An explicit null lookup does not prevent a later ServiceKey from injecting a non-null owning key. Inherited keys are evaluated against the actual request, and null/unkeyed contexts still ignore ServiceKey. Named value/key overrides remain first and bypass unselected attribute binding and owning-key type checks. Contextual decorators use the same corrected metadata.

This is a small change within the existing cached activator. It adds no service lookups, validation provider, graph planner or private DI API access. Attribute inspection uses public reflection when the existing weak type-metadata cache is populated, and effective keys remain resolution-specific. The fix does not change the native original-type activator or bring in the deferred #121 implementation. README and the vNext changelog are updated.

Verification:

  • Tests committed before the implementation: each of net472/net8.0/net9.0/net10.0 produced 24 failures and 138 passing controls. All 162 new cases now pass on every target.
  • Native differential controls cover both attribute orders; non-null, mismatched-type, null and unkeyed contexts; registered/missing/null/throwing dependencies; required/optional parameters; unused/unrelated maps; named value/key overrides; inherited/null lookup modes; all lifetimes; repeated scopes/resolutions; activation counts; native/snapshot/diagnostic providers; and contextual decorators.
  • The exact standalone issue probe reproduces the original dependency versus blue discrepancy on current develop and published Mammoth 0.8.0 on all four targets with DI 10.0.0.
  • Local restore and Release solution build with ContinuousIntegrationBuild=True passed. An initial reused-worker build failed with access errors; disabling build servers produced a successful final build. Initial fixture/nullable compiler warnings were corrected. Final build has zero errors or compiler/analyzer warnings, with only the two existing net472 support warnings for Microsoft.Extensions.Telemetry.Abstractions and Microsoft.Extensions.Diagnostics.Testing 10.0.0.
  • Local full suite passed 2,740 tests per target: 10,960 total, zero failed/skipped. net472 ran on .NET Framework 4.8.9345.0; modern runtimes were 8.0.31, 9.0.20 and 10.0.12.
  • Local native DI 10 hot-cache probes passed on all four targets, each with 100 interleaved enumerations after observed native compilation. Whitespace check passed. No applicable final local check was unavailable.

CI for the exact final commit 94af8ba1eaadedb39a4075ea8c9eb5dbe547541f succeeded: run 37932581363. Windows restore and Release build passed; the full suite passed 2,740 tests per target (net472/net8.0/net9.0/net10.0), 10,960 total, with zero failed/skipped. All four native DI hot-cache probes passed with observed accessor replacement and 100 interleaved enumerations. Only the same two net472 package-support warnings appeared. Pack and Publish were skipped. No applicable final verification was unavailable.

Work stops for review of PR #125 before another issue. #121/PR #124 remain on hold. After this fix is reviewed and merged, a release-validation checkpoint should explicitly acknowledge deferred #121; passing checks here do not establish full native graph-planning parity. No merge, tag, release-branch push, package publication or release action was performed.

@AGiorgetti
AGiorgetti marked this pull request as ready for review October 9, 2026 12:57
@AGiorgetti
AGiorgetti merged commit bc4e765 into develop Oct 9, 2026
2 checks passed
@AGiorgetti
AGiorgetti deleted the codex/fix-122-key-attribute-order branch October 9, 2026 13:01
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.

DependsOn changes native precedence when FromKeyedServices and ServiceKey share a parameter

1 participant