ContextR.Resolution¶
ContextR.Resolution provides ingress context resolution for ContextR.
It is separate from Propagation:
- Resolution: derive context from trusted runtime sources (JWT claims, host/path, custom sources).
- Propagation: move context across transport boundaries (HTTP/gRPC/events).
Why this exists¶
In distributed systems, first-hop context creation and downstream context propagation are different responsibilities.
Mixing them leads to boilerplate and inconsistent trust rules.
Resolution provides a unified place to decide final context values at ingress.
Core contracts¶
IContextResolver<TContext>: resolve context value from runtime source.IContextResolutionPolicy<TContext>: choose final value when both resolved and propagated values exist.IContextResolutionOrchestrator<TContext>: execute resolver + policy and optionally write ambient context.ContextResolutionContext: boundary/domain metadata.ContextIngressBoundary:ExternalorInternal.ContextResolutionResult<TContext>andContextResolutionSource.
Default precedence model¶
Default policy is trust-boundary split:
- External ingress: resolver wins over propagated
- Internal ingress: propagated wins over resolver
Fallback behavior:
- if only one source exists, that source is used
- if no source exists, result is empty (
Source = None)
Registration API¶
Enable resolution from inside AddContextR(...):
builder.Services.AddContextR(ctx =>
{
ctx.Add<UserContext>(reg => reg
.AddResolution(r => r
.UseResolver<JwtUserContextResolver>()));
});
UseResolver(...) and UseResolutionPolicy(...) also auto-enable resolution services.
That means these two patterns are both valid:
- direct resolver/policy registration and let ContextR auto-register resolution services (recommended)
- explicit package bootstrap with
AddContextRResolution(), then resolver/policy registration (advanced/optional)
Resolver registration (recommended):
Or direct resolver registration without nested builder:
Or delegate-based resolver:
Policy registration:
ctx.Add<UserContext>(reg => reg
.AddResolution(r => r
.UseResolutionPolicy<CustomUserResolutionPolicy>()));
Or delegate-based policy:
ctx.Add<UserContext>(reg => reg
.UseResolutionPolicy<UserContext>(policyContext =>
new ContextResolutionResult<UserContext>
{
Context = policyContext.ResolvedContext,
Source = ContextResolutionSource.Policy
}));
Orchestrator usage¶
var result = orchestrator.ResolveAndWrite(
new ContextResolutionContext
{
Boundary = ContextIngressBoundary.External,
Domain = "web-api"
},
propagatedContext);
ResolveAndWrite writes final context through IContextWriter when a value is selected.
Real-world example¶
For a production-style gateway flow (JWT claims -> UserContext -> downstream propagation), see:
Package boundaries¶
ContextR.Resolution is optional and depends on ContextR core primitives (IContextWriter, domains, snapshots/accessor model).
Use this package in gateway/ingress services that need first-hop context creation policies.