Repository navigation
Decoration changes native type-registration constructor preference and ambiguity rules #111
Description
Activity
Implemented #111 in PR #118, awaiting review at
e3feae6835e68c5a7edee4f0839eb9a1af805ad0.Original implementation-type descriptors now use the existing native-compatible activator: ignore ActivatorUtilitiesConstructor attributes, accept native-valid parameter permutations/subsets, and reject unrelated parameter-type ambiguity before dependency activation. Keyed originals retain their actual service key; unkeyed originals receive no private decoration-slot key. Original factory delegates and instances, nonempty DependsOn maps, and newly added decorators keep their existing policies and ownership.
As explicitly approved, plain BuildServiceProvider() remains supported. Built-in availability checks share the existing guarded descriptor fallback. Generic-constraint validation prefers Mammoth's snapshot and otherwise weakly caches an internal snapshot from the recognized native probe's copied descriptors. Public probes cannot detect invalid constraints on unselected candidates; resolving dependencies to test them would invoke factories too early. This reuses the existing private field lookup, adds no new private lookup, and preserves exact/AnyKey precedence and metadata isolation. The architecture document and source comments explain this version-sensitive fallback.
Tests were added first: 144 failed, 135 controls passed per target before the fix, including a repeat with the corrected final validation control. All 279 new cases now pass, covering constructor selection, contextual keys, repeated layers, all lifetimes, type/factory/instance ownership, disposal, built-ins, generic constraints/overrides, metadata isolation, exceptions and retained decorator/map policies.
Final local Release restore/build/full suite passed: 2,257 tests per target, 9,028 total, zero failed/skipped, on Windows net472 and net8.0/net9.0/net10.0. All four native hot-cache probes passed 100 interleaved enumerations after compilation. Only the two existing net472 support warnings for Telemetry.Abstractions and Diagnostics.Testing 10.0.0 remain; no compiler/analyzer warnings.
CI run 37806283550 passed for the exact final head; downloaded logs confirm all test totals and cache probes. Pack and Publish were skipped. No applicable check was unavailable.
The vNext changelog is updated. Stopping for your review and explicit instruction to continue.
- added a commit that references this issue
on Oct 9, 2026 - added a commit that references this issue
on Oct 9, 2026
Priority: P2
Problem
Decorate replaces a normal implementation-type descriptor with a private factory, then reactivates the original implementation using ActivatorUtilities or ConstructorActivator.CreateKeyed. Those activators use different constructor rules from standard DI type registrations. Adding a simple forwarding decorator therefore changes which original constructor runs, rejects native-valid constructor sets, and accepts native-invalid sets.
Related to closed #88, which corrected the same category of divergence in ordinary diagnostic wrappers; the decorator-inner activation path remains affected.
Source.
Reproduction
Save this project as
artifacts/review-decorator-native-constructors/repro.csproj, withProgram.csbeside it, in the reviewed checkout.Run
dotnet run --project artifacts/review-decorator-native-constructors/repro.csproj -c Release -f net472, then repeat with net8.0, net9.0 and net10.0.Observed versus expected
The result is the same for keyed and unkeyed registrations on every supported target:
The larger executed comparison also covered contextual ServiceKey constructors, with the same divergence. Factory-only providers and ordinary diagnostic activation retain native behavior.
Preserve native constructor rules for the original implementation-type registration. Native type activation ignores ActivatorUtilitiesConstructor and compares parameter-type sets for ambiguity; newly added decorators may retain their own documented construction policy. Reuse or factor the native-compatible activation logic without requiring metadata absent from ordinary BuildServiceProvider. Test keyed/unkeyed/contextual originals, repeated layers, all lifetimes and disposal ownership. Do not change the separately documented nonempty DependsOn selection rules.
Verification
Executed against ead376e with Microsoft.Extensions.DependencyInjection 10.0.0, targeting net472 on Windows .NET Framework 4.8.9345.0, .NET 8.0.31, .NET 9.0.20 and .NET 10.0.12. The larger native-comparison harness also reproduced the failure with published Mammoth 0.8.0 on net472 and .NET 10; this is pre-existing behavior, not a newly introduced performance regression. No library source changes were made.
Prepared with OpenAI Codex.