DcsvIo.D2.Context.Abstractions
0.1.1
dotnet add package DcsvIo.D2.Context.Abstractions --version 0.1.1
NuGet\Install-Package DcsvIo.D2.Context.Abstractions -Version 0.1.1
<PackageReference Include="DcsvIo.D2.Context.Abstractions" Version="0.1.1" />
<PackageVersion Include="DcsvIo.D2.Context.Abstractions" Version="0.1.1" />
<PackageReference Include="DcsvIo.D2.Context.Abstractions" />
paket add DcsvIo.D2.Context.Abstractions --version 0.1.1
#r "nuget: DcsvIo.D2.Context.Abstractions, 0.1.1"
#:package DcsvIo.D2.Context.Abstractions@0.1.1
#addin nuget:?package=DcsvIo.D2.Context.Abstractions&version=0.1.1
#tool nuget:?package=DcsvIo.D2.Context.Abstractions&version=0.1.1
DcsvIo.D2.Context.Abstractions
Single-lib home for every spec-driven context primitive. The request-context contract spec is the source of truth — DcsvIo.D2.Context.SourceGen reads it at build time and emits five files into this assembly (re-emitted on every dotnet build; do not hand-edit):
| Type | Kind | Purpose |
|---|---|---|
IRequestContext |
interface | Read-only contract domain code consumes (extends IAuthContext). |
MutableRequestContext |
sealed class | Settable concrete; per-scope DI registration; HTTP / messaging middleware populates this. Implements IRequestContext. Includes FromClaims + FromJwtPayloadNoValidation factories. |
PropagatedContext |
sealed record | Cross-hop subset — every property the spec marks propagate: true (RequestId, RequestPath, SessionFingerprint, CurrentFingerprint, RiskScore, WhoIsHashId today). Identity (UserId / OrgId / Scopes / ActorChain) is never propagated — it rebuilds from the JWT at every sync hop. |
PropagatedContextExtensions |
static class | Two projections: IRequestContext.ToPropagatedContext() (snapshot) and MutableRequestContext.ApplyPropagatedContext(PropagatedContext?) (apply). |
PropagatedContextSerializer |
static class | Wire codec — base64url-of-JSON for the x-d2-context header (AMQP / gRPC / HTTP). MAX_HEADER_LENGTH = 2048 global cap; per-field length validation baked from each propagatable field's maxLength annotation in the spec. TryDecode returns null on any failure — propagation is opportunistic, never required. |
Install
dotnet add package DcsvIo.D2.Context.Abstractions
Hand-written RFC helpers
Hand-written RFC-spec'd helpers ship here too (the spec doesn't describe JWT-claim parsing semantics — RFCs do — so these stay imperative):
| Type | RFC | Purpose |
|---|---|---|
ActorChainParser |
RFC 8693 §2.1 | Parses act claim into IReadOnlyList<ActorEntry>, depth-limited strict-mode. Used by MutableRequestContext.FromClaims / FromJwtPayloadNoValidation. |
ScopeClaimParser |
RFC 6749 §3.3 | Parses scope claim — SP-only string OR JSON array — into IReadOnlySet<string>. |
MalformedActorChainException |
— | Surface for actor-chain parse failures. |
In-host establishment boundaries
Two in-host establishment boundaries plus their shared call-path helper ship here too:
| Type | Purpose |
|---|---|
InProcessModuleBoundary |
Extension method IRequestContext.EstablishInProcessModule(callingModuleId, targetModuleId, IClock) — the generated in-host module façade (the I<Module>Api leaf) calls this before dispatching into another module inside the same host. Sets Origin = RequestOrigin.InProcessModule, ImmediateCaller = the calling module's own id, and appends a CallPathKind.ModuleHop entry. No-op-safe when the context is not a MutableRequestContext (e.g. a read-only test double). |
SystemRequestContextBootstrap |
Extension method IServiceProvider.EstablishSystemContext(hostServiceId, IClock) — low-level bootstrap used by ISystemWorkScopeFactory (not for direct module use). Resolves the scope's MutableRequestContext (throws InvalidOperationException if the scope does not register one), sets Origin = RequestOrigin.System, ImmediateCaller = the host's own service id, and starts a fresh single-entry CallPath with a CallPathKind.System entry. |
ISystemWorkScope / ISystemWorkScopeFactory + AddD2SystemWorkPlane() |
Platform System work plane — the only sanctioned entry for hosted/background authority-bearing work. BeginAsync creates a DI scope, always calls EstablishSystemContext (host service id from D2WorkloadIdentityOptions), and returns a disposable scope with Services. Modules consume the factory; they never register IRequestContext / MutableRequestContext themselves. Hosts wire AddD2SystemWorkPlane() once at composition root. Host JWT / gRPC dual-path resolvers replace the plain Mutable default so inbound requests still prefer HttpContext.Items[REQUEST_CONTEXT] while System workers fall through to scoped Mutable. |
CallPathOps |
Pure static helper Append(existing, id, kind, timestamp) → IReadOnlyList<CallPathEntry> shared by every establishment boundary (in this lib and in host-supplied HTTP/gRPC transport bindings). Depth-bounds the accumulated call-path at MAX_CALL_PATH_DEPTH (16) by trimming the oldest entries — keeps the field bounded even though a request cannot grow it without limit hop-by-hop. Throws ArgumentException on a null/empty/whitespace id (a missing self-identity is a misconfiguration, not a silently-dropped entry). |
Origin / ImmediateCaller are never propagated (recomputed fresh, locally, by every establishment boundary); CallPath is the one field here that IS propagated (propagate: true, depth-bounded) — see DcsvIo.D2.Auth.Abstractions for the full local-fact-vs-propagated-telemetry model.
Spec annotations driving the codegen
Two annotations control the propagated subset, both on each property in the spec:
propagate: true | false(default false) — does this property flow cross-hop inx-d2-context?maxLength: <int>(optional) — wire-level per-field length cap; the codegen-emittedTryDecoderejects oversized values.
Identity fields (UserId / OrgId / Scopes / ActorChain) MUST NOT be marked propagate: true. Those rebuild from the JWT at every sync hop; for async events the consumer-side handler doesn't have one and shouldn't claim caller identity.
Cross-language story
The wire format (base64url of canonical JSON) is language-neutral; per-field caps come from the same JSON spec; the projection extensions are mechanical given the field set. Any language consumer that mirrors the spec is bug-compatible. One JSON spec → N language-specific abstractions libs.
Spec → IRequestContext shape
6 sections (4 are WhoIs sub-groupings):
- Tracing:
TraceId,RequestId,RequestPath - Network:
ClientIp - Fingerprints:
SessionFingerprint,CurrentFingerprint,RiskScore - WhoIs — Admin Location:
WhoIsHashId,AdminLocationHashId,City,Region,SubdivisionCode,CountryCode,PostalCode - WhoIs — Coordinates:
Latitude,Longitude,Geohash - WhoIs — Network Privacy:
IsVpn,IsProxy,IsTor,IsHosting - WhoIs — ASN:
Asn,AsnName,AsnType
Plus everything from IAuthContext (token / identity / organization / impersonation / scopes).
Dependencies
DcsvIo.D2.AuthContext.Abstractions—IAuthContextbase interface +IAuthContextExtensions.DcsvIo.D2.Auth.Abstractions—ActorEntry, enums (ActorKind,ImpersonationKind,OrgType,Role,RequestOrigin,CallPathKind), andCallPathEntry— the establishment vocabularyInProcessModuleBoundary/SystemRequestContextBootstrap/CallPathOpsoperate on.DcsvIo.D2.Utilities—Falsey()/Truthy()/TryParseTruthyNullextensions used by parsers;ThrowIfFalsey()guards on the establishment boundaries.DcsvIo.D2.Time—IClockinjection seam theInProcessModuleBoundary+SystemRequestContextBootstrapestablishment boundaries use to timestamp the call-path entry they append.DcsvIo.D2.Context.SourceGen— analyzer-only.
Sister packages: DcsvIo.D2.AuthContext.Abstractions, DcsvIo.D2.Auth.Abstractions.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- DcsvIo.D2.Auth.Abstractions (>= 0.1.1)
- DcsvIo.D2.AuthContext.Abstractions (>= 0.1.1)
- DcsvIo.D2.Time (>= 0.1.1)
- DcsvIo.D2.Utilities (>= 0.1.1)
- dotenv.net (>= 4.0.2)
- JetBrains.Annotations (>= 2025.2.4)
- Microsoft.EntityFrameworkCore (>= 10.0.7)
- Microsoft.EntityFrameworkCore.Relational (>= 10.0.7)
- Microsoft.Extensions.Caching.Abstractions (>= 10.0.7)
- Microsoft.Extensions.Caching.Memory (>= 10.0.7)
- Microsoft.Extensions.Configuration.Abstractions (>= 10.0.7)
- Microsoft.Extensions.DependencyInjection (>= 10.0.7)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.7)
- Microsoft.Extensions.Logging (>= 10.0.7)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.7)
- Microsoft.Extensions.Options (>= 10.0.7)
- Microsoft.IdentityModel.Tokens (>= 8.16.0)
- NodaTime (>= 3.2.2)
- Npgsql (>= 10.0.2)
- Npgsql.EntityFrameworkCore.PostgreSQL (>= 10.0.1)
- Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime (>= 10.0.1)
NuGet packages (6)
Showing the top 5 NuGet packages that depend on DcsvIo.D2.Context.Abstractions:
| Package | Downloads |
|---|---|
|
DcsvIo.D2.Geo.Abstractions
Strongly-typed ISO geo reference-data type surface for D2 (countries, subdivisions, currencies, languages, locales, timezones) without catalog data. |
|
|
DcsvIo.D2.Handler.Abstractions
Domain-safe slice of the D2 handler stack — IHandler, IHandlerContext, and HandlerOptions. |
|
|
DcsvIo.D2.Handler
BaseHandler for D2 — the abstract base every handler inherits, providing scope pre-checks, OpenTelemetry activity and metrics, log scope, and a universal try/catch. |
|
|
DcsvIo.D2.Logging
Serilog configuration, the [RedactData] PII-enforcement layer, and request-logging middleware for D2 services. |
|
|
DcsvIo.D2.Messaging.RabbitMq
Default RabbitMQ implementation of the D2 messaging abstractions — publishing, subscribing, encryption frames, and dead-letter handling. |
GitHub repositories
This package is not used by any popular GitHub repositories.