Skip to content

Create AnyKey adapter registrations per registry (#1497) - #1498

Merged
tillig merged 2 commits into
developfrom
feature/issue-1497
Sep 15, 2026
Merged

tillig merged 2 commits into
developfrom
feature/issue-1497

Conversation

@tillig

@tillig tillig commented Sep 15, 2026 •

Copy link
Copy Markdown
Member

Fixes #1497

Proposed Changes

  • AnyKeyRegistrationSource no longer caches the adapter registrations it creates. The cache added in Performance improvements #1478 is keyed only by the requested KeyedService, but the source instance is shared with every child scope registry, so one adapter instance got handed to several registries. A registry owns the registrations added to it - it builds their pipelines and disposes them - and an adapter has to target the any-key registration visible in the registry that asked for it. Sharing one broke all three:
    • Autofac.Extensions.DependencyInjection adds middleware from Registered, which throws InvalidOperationException on a registration whose pipeline another registry already built. This is the reported symptom.
    • Disposing the scope that resolved the key first disposes the adapter every other scope was handed, so the next resolve throws ObjectDisposedException. No MEDI involved.
    • Sibling scopes with different any-key registrations both resolved the first scope's implementation.
  • Deleted ReflectionCacheKeyedServiceDictionary, which existed only to hold that cache.
  • Added KeyedAnyKeyChildScopeBenchmark to cover the affected path.

Regression Tests

Four tests in AnyKeyRegistrationSourceTests: one per symptom above, plus the invariant that two registries never hold the same adapter instance. All four fail against 9.3.2.

Performance

dotnet run -c Release --project bench/Autofac.Benchmarks -- --baseline-version 9.3.2 --filter *KeyedAnyKeyChildScope*, net10.0:

Benchmark 9.3.2 This PR
ResolveDirectKeyFromNewChildScope (control, no any-key) 3,191 ns / 14.55 KB 3,188 ns / 14.55 KB
ResolveAnyKeyFromExistingChildScope 180 ns / 1.09 KB 182 ns / 1.09 KB
ResolveAnyKeyFromNewChildScope throws 4,040 ns / 17.36 KB

Only the path that now builds an adapter per registry moves: roughly 850 ns and 2.8 KB per new scope registry, against the direct-keyed control in the same run. It has no baseline number because every released version with any-key support throws ObjectDisposedException there. KeyedAnyKeySimpleBenchmark and the root container resolves are unchanged.

Unblocking CI

Two commits: the fix above, plus one for CI, which was already failing on develop.

  • Microsoft.SourceLink.GitHub 8.0.0 → 10.0.401. It carries Microsoft.Build.Tasks.Git 8.0.0, which CVE-2026-62900 covers with no patched 8.x release, so NuGet audit fails the Release build. Every other repo in the org is already on 10.0.3xx/4xx.
  • VerifyAotWarnings ignored the fixture build's exit code, so that restore failure surfaced as "an annotation may have been lost in core Autofac" instead of the actual error. It now checks the exit code first.

Sibling repos pinning 10.0.300 or 10.0.301 are in the same advisory range and will hit this too.

@codecov

codecov Bot commented Sep 15, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 78.23%. Comparing base (6a2e0f8) to head (53020b9).

Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #1498      +/-   ##
===========================================
- Coverage    78.26%   78.23%   -0.03%     
===========================================
  Files          218      217       -1     
  Lines         5948     5928      -20     
  Branches      1274     1269       -5     
===========================================
- Hits          4655     4638      -17     
  Misses         753      753              
+ Partials       540      537       -3     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

The adapter cache handed one registration to every registry that asked for it, so the scope that got there first built its pipeline and disposed it - leaving other scopes unable to add middleware (#1497), resolving through a disposed activator, or adapting another scope's registration.
Microsoft.SourceLink.GitHub 8.0.0 brings Microsoft.Build.Tasks.Git 8.0.0, which the advisory has no patched 8.x release for, so NuGet audit fails the Release build. VerifyAotWarnings ignored the fixture's exit code, which turned that restore failure into a claim that an AOT annotation had been lost - it now reports the build failure instead.
@tillig
tillig merged commit 3084244 into develop Sep 15, 2026
14 checks passed
@tillig
tillig deleted the feature/issue-1497 branch September 17, 2026 21:28
This was referenced Sep 18, 2026
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.

Exception when attempting to resolve service registered with KeyedService.AnyKey from multitenant container

1 participant