Skip to content

fix: resolve a contracted registration's dependencies without its contract - #336

Merged
glennawatson merged 1 commit into
mainfrom
fix/dependency-contract
Sep 26, 2026
Merged

glennawatson merged 1 commit into
mainfrom
fix/dependency-contract

Conversation

@glennawatson

Copy link
Copy Markdown
Contributor

Summary

A service registered under a contract resolves its dependencies from their registrations without a contract.

  • Constructor parameters and injected properties no longer inherit the registration's contract. Register<ViewBase, V1>("V1") now resolves V1's S1 parameter with GetService<S1>(), not GetService<S1>("V1"). The contract still applies to the registration itself, including both registrations of a lazy singleton.
  • The README says how a contracted registration's dependencies resolve.

Why

Since the move to an incremental generator, a registration's contract was passed to every dependency it resolved. A contracted service whose dependencies were registered without a contract threw InvalidOperationException: Dependency '...' with contract V1 not registered with Splat resolver. The original generator resolved dependencies without a contract.

Closes #305

Breaking changes

Dependencies registered only under the service's contract no longer resolve.

  • A dependency of a contracted registration that was registered only under that same contract no longer resolves. Register it without a contract as well.

How this was verified

  • A new test runs registrations the generator wrote into the test assembly against Splat and resolves the issue's scenario. It fails on main with the exception from the issue.
  • Snapshots of contracted registrations with dependencies show them resolved without the contract.

Notes for the reviewer

The change is in CodeGeneration/CodeGenerator.cs; the snapshot changes follow from it.

  • The generated file now needs only one throw helper, since a missing dependency is never reported under a contract.
  • The generator test project now also references the generator as an analyzer, so RuntimeResolutionTests calls the real generated SetupIOC.

Checklist

  • I have read the Contribute guide
  • The PR title follows Conventional Commits
  • Tests cover this change, or the summary says why they do not
  • New or changed public API has XML documentation

@codecov

codecov Bot commented Sep 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (9679373) to head (8c4f32a).

Additional details and impacted files
@@            Coverage Diff            @@
##              main      #336   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           20        20           
  Lines          976       967    -9     
  Branches       171       168    -3     
=========================================
- Hits           976       967    -9     

☔ 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.

@glennawatson
glennawatson merged commit 1bf3533 into main Sep 26, 2026
12 checks passed
@glennawatson
glennawatson deleted the fix/dependency-contract branch September 26, 2026 10:12
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.

[Bug]: Source Generator Incorrectly Passes Contract Name to Constructor Dependency Resolution

1 participant