Validation reports problems by severity, and names the IScopedProvider misuse it used to swallow - #64
Merged
Merged
Conversation
shellicar
marked this pull request as ready for review
July 27, 2026 15:57
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
validate()no longer reports the tokens the engine binds itself (IServiceProvider,IScopedProvider,IResolutionScope) as missing targets.errorsfromwarnings, each problem carrying its severity, and only errors make a report invalid or block a build.ValidationErrorcarries the same two lists.CaptivePolicy.Strictand a warning underCaptivePolicy.Disposal.IScopedProvideris reported as a scope mismatch, on everything a singleton can reach as well as on the singleton itself: an error where no boundary can ever serve it, a warning where only the root cannot.IScopedProvidernow throwsScopeMismatchErrorrather than silently handing over the root provider, and the root'sresolveno longer accepts the token at all.validate()warns when a singleton holds a scoped or resolve dependency, which is shared more narrowly than the singleton itself.resolveAllanswers a surface token with the one surface its reach allows, instead of an empty list.Background
A surface token now declares how far it reaches:
rootis always the root surface,nearestis the boundary being resolved from with the root counting as one, andscopeis the boundary being resolved from with the root excluded. One kind previously meant both of the last two, which is why the root answered forIScopedProviderat all.The two reports on a singleton's dependencies answer different questions and are deliberately independent.
SharingMismatchasks which instance you get, and is reported whateverCaptivePolicysays.CaptiveDependencyasks whether it is disposed underneath you, and stays governed by the policy. A scoped dependency in a singleton is both.resolveAllkeeps its own contract rather than borrowing the single door's. It answers "how many are there", so an empty list where a reach allows nothing is the same answer it already gives for a token with no registrations, and onlyresolverefuses.The engine spec composes all three reaches against tokens nothing else uses, so each is proven through both doors under both resolution strategies.