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
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="DcsvIo.D2.Context.Abstractions" Version="0.1.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="DcsvIo.D2.Context.Abstractions" Version="0.1.1" />
                    
Directory.Packages.props
<PackageReference Include="DcsvIo.D2.Context.Abstractions" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add DcsvIo.D2.Context.Abstractions --version 0.1.1
                    
#r "nuget: DcsvIo.D2.Context.Abstractions, 0.1.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package DcsvIo.D2.Context.Abstractions@0.1.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=DcsvIo.D2.Context.Abstractions&version=0.1.1
                    
Install as a Cake Addin
#tool nuget:?package=DcsvIo.D2.Context.Abstractions&version=0.1.1
                    
Install as a Cake Tool

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 in x-d2-context?
  • maxLength: <int> (optional) — wire-level per-field length cap; the codegen-emitted TryDecode rejects 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.AbstractionsIAuthContext base interface + IAuthContextExtensions.
  • DcsvIo.D2.Auth.AbstractionsActorEntry, enums (ActorKind, ImpersonationKind, OrgType, Role, RequestOrigin, CallPathKind), and CallPathEntry — the establishment vocabulary InProcessModuleBoundary / SystemRequestContextBootstrap / CallPathOps operate on.
  • DcsvIo.D2.UtilitiesFalsey() / Truthy() / TryParseTruthyNull extensions used by parsers; ThrowIfFalsey() guards on the establishment boundaries.
  • DcsvIo.D2.TimeIClock injection seam the InProcessModuleBoundary + SystemRequestContextBootstrap establishment 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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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.

Version Downloads Last Updated
0.1.1 240 7/17/2026
0.1.0 244 7/17/2026