Kanject.Core.Adapter
The outbound HTTP integration layer. Typed HttpClient registration, resilient retries, authentication and header helpers, health pings, AOT-safe JSON overloads — plus a source generator that turns declarative endpoint contracts into production-ready adapter methods.
Use it when a service needs a stable boundary around a payment gateway, shipping carrier, CRM, internal microservice, or any other HTTP API. Application code depends on a typed adapter instead of spreading URLs, credentials, serialization, and status-code handling across controllers and domain services.
Install
dotnet add package Kanject.Core.Adapter Kanject.Core.Adapter.Annotations (the endpoint source generator) is included transitively, so generated adapters normally need no second package reference.
A generated adapter
Declare the contract — auth scheme, base URL, endpoints, per-endpoint headers — and the generator emits the adapter methods:
[AdapterAuth( AuthScheme.ApiKey, SettingsType = typeof(ParcelApiOptions), HeaderMappings = ["X-Api-Key:ApiKey"])][AdapterBaseUrl(nameof(ParcelApiOptions.BaseUrl))][AdapterJsonSerializerContext(typeof(ParcelAdapterJsonContext))]public partial class ParcelAdapter( HttpClient httpClient, ParcelApiOptions settings) : AbstractServiceAdapter(httpClient){ private readonly ParcelApiOptions _settings = settings; [AdapterEndpoint(HttpVerb.Post, "v1/shipments")] [AdapterHeader("Idempotency-Key", "{request.IdempotencyKey}")] public virtual partial Task<CreateShipmentResponse?> CreateShipmentAsync( CreateShipmentRequest request, CancellationToken cancellationToken); [AdapterEndpoint( HttpVerb.Get, "v1/shipments/{ShipmentId}", NotFoundReturnsNull = true)] public virtual partial Task<ShipmentStatus?> GetShipmentAsync( ShipmentLookup request, CancellationToken cancellationToken);} Two authoring styles
- Generated endpoints — attributes, request/response DTOs, and
partialmethod signatures. Best for most integrations and documentation-first contracts. - Hand-written adapter — subclass
AbstractServiceAdapterand callGetAsync/PostAsync/PutAsync/DeleteAsyncdirectly. Best for custom protocols, unusual response handling, or incremental migration.
Both styles share the same AbstractServiceAdapter, HttpClientFactory registration, retry policy, cancellation flow, and response helpers — you can mix them in one adapter.
What ships with it
- Auth schemes — API key, bearer token, and header-mapped credentials declared once per adapter (
[AdapterAuth]) - Resilient retries — a retry policy on the shared base class, tuned for transient upstream failures
- Settings-driven config — base URLs, keys, and header values resolve from typed options (
{settings.…}templates) - Error behaviour per endpoint —
NotFoundReturnsNull, custom error messages, status-code mapping - Health pings — a built-in upstream reachability check (opt out per adapter with
[AdapterDisablePing]) - AOT-safe JSON —
[AdapterJsonSerializerContext]wires source-generated serializer metadata, no reflection