A generated container already holds the message it would throw for a service it has but will not hand over synchronously: an async-initialized one reached through a synchronous path, or a disposable transient asked on the root under strict lifetime safety. Only Resolve could reach it. TryResolve and IsResolvable report such a service exactly as they report one with no registration at all, which is right for what each answers and useless for telling the two apart, so a host adapter that must answer an unknown type with null, because that is how it says "not mine" to a framework, had to turn the container's specific message into the framework's generic one.
IAwaitenContainerMetadata.WithheldReason returns that message, or null when there is no such reason. It is emitted over the same tables Resolve throws from, unkeyed and keyed alike, so the two answers are the same answer by construction rather than by agreement, and both Resolve overloads now read the one lookup. The member is emitted on the Root because the answer is the Root's: a child scope builds a root-withheld transient normally.
The lookup is emitted only when one of the tables it reads exists, so a container that withholds nothing reports the constant instead of carrying a helper whose every path returns null. Whether it does is decided once, where the __withheld table is emitted, and passed to the emitters that read it, so the decision to emit the table cannot drift from the decision to read it. The Root needs that answer and is emitted first, so the Scope is emitted into a buffer and the generated file is unchanged for every container that does withhold something.
The bridge uses it, so GetService and GetKeyedService throw the guidance where they used to return null, and IsService and IsKeyedService report such a service as existing. That extends what the provider already did for a root-withheld disposable transient to the async-withheld case, on the same reasoning: a silent null lets a host bind the value from somewhere else and fail far from the cause. Four tests that pinned the old silence are inverted, and a probe sweep pins that the keyed pair still agree.
AWT135 gains a clause pointing a host-integration adapter at suppression, because "inject the dependency you need instead" is wrong advice for a type whose whole job is holding the resolver, and the sanctioned answer was documented only in the analyzer's own remarks. The diagnostics page gains the example, and the example is compiled and covered rather than only written down, because it is the reference an adapter author copies. It honours the collection convention the bridge page asks of such an adapter: an unresolvable IEnumerable<T> enumerates empty rather than coming back null, unless the element type resolves, in which case members exist that an empty sequence would drop.
Adding a member to IAwaitenContainerMetadata is source-breaking for a hand-written implementation, which the interface now says not to write; netstandard2.0 rules out a default implementation.
A generated container already holds the message it would throw for a service it has but will not hand over synchronously: an async-initialized one reached through a synchronous path, or a disposable transient asked on the root under strict lifetime safety. Only Resolve could reach it. TryResolve and IsResolvable report such a service exactly as they report one with no registration at all, which is right for what each answers and useless for telling the two apart, so a host adapter that must answer an unknown type with null, because that is how it says "not mine" to a framework, had to turn the container's specific message into the framework's generic one.
IAwaitenContainerMetadata.WithheldReason returns that message, or null when there is no such reason. It is emitted over the same tables Resolve throws from, unkeyed and keyed alike, so the two answers are the same answer by construction rather than by agreement, and both Resolve overloads now read the one lookup. The member is emitted on the Root because the answer is the Root's: a child scope builds a root-withheld transient normally.
The bridge uses it, so GetService and GetKeyedService throw the guidance where they used to return null, and IsService and IsKeyedService report such a service as existing. That extends what the provider already did for a root-withheld disposable transient to the async-withheld case, on the same reasoning: a silent null lets a host bind the value from somewhere else and fail far from the cause. Four tests that pinned the old silence are inverted, and a probe sweep pins that the keyed pair still agree.
AWT135 gains a clause pointing a host-integration adapter at suppression, because "inject the dependency you need instead" is wrong advice for a type whose whole job is holding the resolver, and the sanctioned answer was documented only in the analyzer's own remarks. The diagnostics page gains the example.
Adding a member to IAwaitenContainerMetadata is source-breaking for a hand-written implementation, which the interface now says not to write; netstandard2.0 rules out a default implementation.