TieredProviderSelectorServiceCollectionExtensions
NexusLabs.Needlr.AgentFramework¶
NexusLabs.Needlr.AgentFramework.Providers¶
TieredProviderSelectorServiceCollectionExtensions Class¶
Extension methods that register an ITieredProviderSelector<TQuery,TResult> with optional consumer-supplied TieredProviderSelectorOptions in the DI container.
Inheritance System.Object 🡒 TieredProviderSelectorServiceCollectionExtensions
Remarks¶
Wraps the boilerplate of resolving providers, the quota gate, the execution-context accessor, and System.TimeProvider from the container so consumers do not have to hand-roll the same factory in every host.
Registration semantics: last-wins (override-friendly). The extension uses
AddSingleton (not TryAddSingleton). If the same (TQuery, TResult)
pair is registered multiple times — for example, by two plugins —
System.IServiceProvider.GetService(System.Type) resolves the LAST descriptor added.
This is the intentional convention for consumer-supplied configuration: a
downstream plugin or test harness can override an upstream plugin's selector
registration without removing it first. (The System.TimeProvider dependency
is registered with TryAddSingleton because it IS framework infrastructure —
first-wins is correct for that.)
Lifetime: Singleton. The selector's per-instance skip cache is the whole point of registering it as a long-lived service — registering as Scoped would reset the cache per request, defeating the purpose. If you need a different lifetime, hand-roll the registration.
Configure delegate evaluation. Both configure overloads invoke the
supplied delegate INSIDE the singleton factory at first resolution, with a real
System.IServiceProvider in scope. This means OnHit callbacks can
resolve other services (loggers, options monitors, telemetry sinks) from the
container — register them BEFORE calling
ITieredProviderSelector<TQuery,TResult>.GetRequiredService for the
first time. The delegate runs exactly once per Singleton lifetime; throw an
System.InvalidOperationException if it returns null.
Methods¶
TieredProviderSelectorServiceCollectionExtensions.AddTieredProviderSelector<TQuery,TResult>(this IServiceCollection) Method¶
Registers an ITieredProviderSelector<TQuery,TResult> as a singleton using Default (PUE-only fall-through, no skip, no callback).
public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddTieredProviderSelector<TQuery,TResult>(this Microsoft.Extensions.DependencyInjection.IServiceCollection services);
Type parameters¶
TQuery
Query type for the selector.
TResult
Result type for the selector.
Parameters¶
services Microsoft.Extensions.DependencyInjection.IServiceCollection
Service collection to add the registration to.
Returns¶
Microsoft.Extensions.DependencyInjection.IServiceCollection
The same services instance for chaining.
Exceptions¶
System.ArgumentNullException
services is null.
TieredProviderSelectorServiceCollectionExtensions.AddTieredProviderSelector<TQuery,TResult>(this IServiceCollection, Func<TieredProviderSelectorOptions,TieredProviderSelectorOptions>) Method¶
Registers an ITieredProviderSelector<TQuery,TResult> as a singleton with consumer-supplied options derived from Default.
public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddTieredProviderSelector<TQuery,TResult>(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Func<NexusLabs.Needlr.AgentFramework.Providers.TieredProviderSelectorOptions,NexusLabs.Needlr.AgentFramework.Providers.TieredProviderSelectorOptions> configure);
Type parameters¶
TQuery
Query type for the selector.
TResult
Result type for the selector.
Parameters¶
services Microsoft.Extensions.DependencyInjection.IServiceCollection
Service collection to add the registration to.
configure System.Func<TieredProviderSelectorOptions,TieredProviderSelectorOptions>
Delegate that receives Default and returns the (possibly mutated) options to use. Runs lazily inside the singleton factory at first resolution. Must not return null.
Returns¶
Microsoft.Extensions.DependencyInjection.IServiceCollection
The same services instance for chaining.
Exceptions¶
System.ArgumentNullException
services or configure is null.
Remarks¶
Use this overload when your OnHit callbacks
(and any other policy fields) do not need access to other DI services. If you
need an ILogger, IOptionsMonitor, or any other container-resolved
service inside your callbacks, use the
AddTieredProviderSelector<TQuery,TResult>(this IServiceCollection, Func<IServiceProvider,TieredProviderSelectorOptions,TieredProviderSelectorOptions>)
overload instead.
TieredProviderSelectorServiceCollectionExtensions.AddTieredProviderSelector<TQuery,TResult>(this IServiceCollection, Func<IServiceProvider,TieredProviderSelectorOptions,TieredProviderSelectorOptions>) Method¶
Registers an ITieredProviderSelector<TQuery,TResult> as a singleton with consumer-supplied options derived from Default, with access to the System.IServiceProvider so policy callbacks can resolve other container services.
public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddTieredProviderSelector<TQuery,TResult>(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Func<System.IServiceProvider,NexusLabs.Needlr.AgentFramework.Providers.TieredProviderSelectorOptions,NexusLabs.Needlr.AgentFramework.Providers.TieredProviderSelectorOptions> configure);
Type parameters¶
TQuery
Query type for the selector.
TResult
Result type for the selector.
Parameters¶
services Microsoft.Extensions.DependencyInjection.IServiceCollection
Service collection to add the registration to.
configure System.Func<System.IServiceProvider,TieredProviderSelectorOptions,TieredProviderSelectorOptions>
Delegate that receives the System.IServiceProvider and Default and returns the (possibly mutated) options to use. Runs lazily inside the singleton factory at first resolution. Must not return null.
Returns¶
Microsoft.Extensions.DependencyInjection.IServiceCollection
The same services instance for chaining.
Exceptions¶
System.ArgumentNullException
services or configure is null.
Example¶
services.AddTieredProviderSelector<WebSearchQuery, IReadOnlyList<WebSearchResult>>(
(sp, opts) =>
{
var logger = sp.GetRequiredService<ILogger<CopilotWebSearchProvider>>();
return opts with
{
FailurePolicies =
[
.. opts.FailurePolicies,
new ProviderFailurePolicy(
Match: ex => ex is CopilotAuthException,
SkipDuration: TimeSpan.FromMinutes(5),
OnHit: ctx =>
{
logger.LogWarning(ctx.Exception,
"Provider {Provider} skipped until {Until}",
ctx.ProviderName, ctx.SkipUntil);
return ValueTask.CompletedTask;
}),
],
};
});