Stratara.Resilience
3.2.2
See the version list below for details.
dotnet add package Stratara.Resilience --version 3.2.2
NuGet\Install-Package Stratara.Resilience -Version 3.2.2
<PackageReference Include="Stratara.Resilience" Version="3.2.2" />
<PackageVersion Include="Stratara.Resilience" Version="3.2.2" />
<PackageReference Include="Stratara.Resilience" />
paket add Stratara.Resilience --version 3.2.2
#r "nuget: Stratara.Resilience, 3.2.2"
#:package Stratara.Resilience@3.2.2
#addin nuget:?package=Stratara.Resilience&version=3.2.2
#tool nuget:?package=Stratara.Resilience&version=3.2.2
Stratara.Resilience
License: MIT.
Polly-based named resilience pipelines pre-wired for Stratara's messaging + outbox dispatch paths.
Quick start
services.AddResiliencePipelines();
// Resolve a specific named pipeline at the call site:
var pipeline = sp.GetRequiredService<ResiliencePipelineProvider<string>>()
.GetPipeline(ResilienceNames.CommandDispatcher);
await pipeline.ExecuteAsync(async ct => {
await DoFlakyWorkAsync(ct);
}, cancellationToken);
Named pipelines
| Name | Constant | Strategy |
|---|---|---|
| Message bus | ResilienceNames.MessageBus |
Exponential retry up to int.MaxValue, 10s → 60s, jitter, then a circuit breaker — opens after 10 consecutive failures and stays open 60s before a trial call |
| Command dispatcher | ResilienceNames.CommandDispatcher |
3 retries, exponential, 200ms, jitter |
| Event bundle dispatcher | ResilienceNames.EventBundleDispatcher |
3 retries, exponential, 200ms, jitter |
| Concurrency conflict | ResilienceNames.ConcurrencyConflict |
Retry only on ConcurrencyConflictException, 5 attempts, short exponential, jitter |
The ResilienceFactory that builds these is internal — interact via DI and ResilienceNames only.
Mediator resilience behavior
Hook a named pipeline into the in-process mediator pipeline per request — no manual ExecuteAsync plumbing:
services.AddResiliencePipelines();
services.AddStrataraResilienceBehavior(); // after AddStrataraValidation() / AddStrataraTenantIsolation()
public sealed record ReserveStock(Guid Id, int Qty) : ICommand<bool>, IResilientRequest
{
public string ResiliencePipelineName => ResilienceNames.ConcurrencyConflict;
}
Any request implementing Stratara.Abstractions.Resilience.IResilientRequest is dispatched inside the
named pipeline it selects; unmarked requests pass straight through. Only mark handlers that are safe
to re-run — naturally idempotent work, or operations guarded by optimistic concurrency (point at the
ConcurrencyConflict pipeline). Register the behavior after the validation / tenant-isolation
behaviors so a retry re-runs the handler, not the guards.
Dependencies
Stratara.Abstractions— forIPipelineBehavior,IResilientRequest, andConcurrencyConflictException.Microsoft.Extensions.DependencyInjection.AbstractionsMicrosoft.Extensions.Resilience(Polly).
| 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
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.8)
- Microsoft.Extensions.Resilience (>= 10.6.0)
- Stratara.Abstractions (>= 3.2.2)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Stratara.Resilience:
| Package | Downloads |
|---|---|
|
Stratara.Shared
Umbrella package for the Stratara framework — source-generated logger extensions for command flows, domain-event helpers, merge primitives, and the Tier-A/B abstractions surface re-exported as one transitive bundle. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 4.0.0 | 0 | 8/31/2026 |
| 4.0.0-preview.1 | 0 | 8/31/2026 |
| 3.4.0 | 154 | 8/28/2026 |
| 3.3.0 | 422 | 8/25/2026 |
| 3.2.3 | 263 | 8/22/2026 |
| 3.2.2 | 842 | 8/14/2026 |
| 3.2.1 | 835 | 8/2/2026 |
| 3.2.0 | 239 | 7/18/2026 |
| 3.1.7 | 379 | 7/1/2026 |
| 3.1.6 | 667 | 6/22/2026 |
| 3.1.5 | 247 | 6/22/2026 |
| 3.1.4 | 261 | 6/15/2026 |
| 3.1.3 | 259 | 6/10/2026 |
| 3.1.2 | 265 | 6/5/2026 |
| 3.1.1 | 321 | 6/1/2026 |
| 3.1.0 | 237 | 5/30/2026 |
| 3.0.23 | 228 | 5/28/2026 |
API keys can now be bootstrapped. Issuance always generated the key itself, which does not fit the
setups where server and caller have to share a key *before* either starts — container orchestration,
CI provisioning, self-hosted bundles, end-to-end test hosts. This release adds an import path for a
key the caller already holds, plus the canonical key format as public API so callers generate values
instead of inventing them.
### Added
- **`IApiKeyStore.ImportAsync` — store a machine key whose raw value the caller already holds.**
Issuance generates the key itself, which is the wrong shape when server and caller must share it
*before* either boots: container orchestration, CI provisioning, self-hosted bundles, end-to-end
test hosts. Without this path, consumers bypassed the store and reimplemented its internals (the
digest format and the machine-key membership row) — a copy that keeps compiling after the store
changes and fails as a runtime 401. Import is idempotent, so it can run unconditionally on every
boot: a value that is already stored returns the existing descriptor and the stored key is never
mutated, so a changed configuration cannot escalate a key's roles or extend its expiry unnoticed.
Revoked, expired, and foreign-tenant values are rejected rather than silently adopted, and
concurrent replicas racing the same first import converge on one key. Machine keys only —
`ApiKeyImportRequest` carries no `UserId`.
- **`ApiKeyFormat` (`Stratara.Abstractions.ApiKeys`) — the canonical raw-key format as public API.**
`CreateRawKey()` generates `stk_` plus the Base64Url encoding of 32 CSPRNG bytes; `IsWellFormed()`
checks that shape. `ImportAsync` accepts only well-formed values: the store keeps its stored
digest unsalted because a generated key carries 256 bits of entropy, and a hand-picked value would
quietly invalidate that. Generate keys out of band with `CreateRawKey()` and keep them in a secret
store — the type lives in the abstractions package so host-builder and orchestration projects can
reach it without referencing the storage implementation.
- **`InMemoryApiKeyStore` (`Stratara.Testing`) — the drop-in double for the API-key store**,
mirroring issuance, import, fail-closed validation, revocation, and the erasure sweeps, and
materializing machine keys into a membership store you can share and inspect.
### Changed
- **API-key lifecycle events are now logged** (`Stratara.Diagnostics` event-ID range 116_000):
import, idempotent repeat, and a repeat that supplied different parameters. Key ids and tenant
ids only — never the raw key or its digest.
- **For implementers of `IApiKeyStore`:** the interface gained `ImportAsync`. Custom implementations
need the new member; callers are unaffected.