Lyo.Resilience 1.0.2

dotnet add package Lyo.Resilience --version 1.0.2
                    
NuGet\Install-Package Lyo.Resilience -Version 1.0.2
                    
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="Lyo.Resilience" Version="1.0.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Lyo.Resilience" Version="1.0.2" />
                    
Directory.Packages.props
<PackageReference Include="Lyo.Resilience" />
                    
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 Lyo.Resilience --version 1.0.2
                    
#r "nuget: Lyo.Resilience, 1.0.2"
                    
#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 Lyo.Resilience@1.0.2
                    
#: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=Lyo.Resilience&version=1.0.2
                    
Install as a Cake Addin
#tool nuget:?package=Lyo.Resilience&version=1.0.2
                    
Install as a Cake Tool

Lyo.Resilience

A thin wrapper around Polly for resilience pipelines with configuration-from-appsettings support and built-in logging. Does not include any library-specific pipeline definitions; pipelines are defined entirely via configuration.

Features

  • Default pipelineslyo-basic and lyo-http with sensible retry and timeout; use without config
  • Load resilience pipelines from appsettings.json (or any IConfiguration source)
  • Support for Retry, Timeout, and CircuitBreaker strategies
  • Built-in logging for retries, timeouts, and circuit breaker state changes
  • Resilience for actionsIResilientExecutor uses default pipeline by default; specify pipeline name to override
  • Result-type support – pass isSuccess predicate to retry when methods return failed Result instead of throwing
  • Resilience for HttpClientAddLyoResilienceHandler() uses default; or pass pipeline name
  • Integrates with Polly.Extensions and ResiliencePipelineProvider<string> for DI

Examples

{
  "TwilioOptions": {
    "AccountSid": "...",
    "AuthToken": "...",
    "DefaultFromPhoneNumber": "+1234567890",
    "Resilience": {
      "sms-pipeline": {
        "Retry": {
          "MaxRetryAttempts": 3,
          "Delay": "00:00:02",
          "MaxDelay": "00:00:30",
          "BackoffType": "Exponential",
          "UseJitter": true
        },
        "Timeout": {
          "Timeout": "00:00:10"
        }
      }
    }
  }
}
services.AddLyoResiliencePipelinesFromOptions(builder.Configuration, "TwilioOptions");
// Loads from TwilioOptions:Resilience

Standalone section example

{
  "Lyo": {
    "ResiliencePipelines": {
      "my-pipeline": {
        "Retry": { "MaxRetryAttempts": 3, "Delay": "00:00:02" },
        "Timeout": { "Timeout": "00:00:10" }
      }
    }
  }
}

Standalone section example (2)

services.AddLyoResiliencePipelines(builder.Configuration); // default: Lyo:ResiliencePipelines
// Or: services.AddLyoResiliencePipelines(builder.Configuration, "CustomSection:Path");

Default pipelines (quick start)

// Adds lyo-basic and lyo-http pipelines (retry + timeout)
builder.Services.AddLyoResilienceDefaults();

// Or: AddResilientExecutor registers defaults automatically
builder.Services.AddResilientExecutor();

Resilience for actions

// Uses default pipeline (lyo-basic)
builder.Services.AddResilientExecutor();

// In a service
public class MyService
{
    private readonly IResilientExecutor _executor;

    public MyService(IResilientExecutor executor) => _executor = executor;

    // Void - uses default pipeline
    public async Task DoWorkAsync(CancellationToken ct) =>
        await _executor.ExecuteAsync(ct => SomeExternalCallAsync(ct), ct);

    // With result - uses default pipeline
    public async Task<string> GetDataAsync(CancellationToken ct) =>
        await _executor.ExecuteAsync(ct => FetchAsync(ct), ct);

    // Specify pipeline
    public async Task DoWorkWithCustomPipelineAsync(CancellationToken ct) =>
        await _executor.ExecuteAsync("my-pipeline", ct => SomeExternalCallAsync(ct), ct);

    // Result types - retry when !result.IsSuccess
    public async Task<Result<EmailRequest>> SendEmailWithRetryAsync(CancellationToken ct) =>
        await _executor.ExecuteAsync(ct => _emailService.SendEmailAsync(builder, ct), r => r.IsSuccess, ct);
}

Resilience for actions (2)

public MyService(ResiliencePipelineProvider<string> pipelineProvider)
{
    var pipeline = pipelineProvider.GetPipeline("my-pipeline");
    await pipeline.ExecuteAsync(async ct => await DoWork(ct), ct);
}

Resilience for HttpClient

// Default pipeline (lyo-http)
builder.Services.AddHttpClient<MyApiClient>(client =>
{
    client.BaseAddress = new Uri("https://api.example.com");
})
.AddLyoResilienceHandler();

// Or specify a pipeline name
builder.Services.AddLyoResiliencePipelines(builder.Configuration);
builder.Services.AddHttpClient<MyApiClient>(/* ... */).AddLyoResilienceHandler("my-pipeline");

Resilience for HttpClient (2)

// In your service - call HttpClient directly; resilience is already on the client
public class MyService
{
    private readonly MyApiClient _apiClient;

    public MyService(MyApiClient apiClient) => _apiClient = apiClient;

    public async Task<Data> GetDataAsync(CancellationToken ct) =>
        await _apiClient.GetAsync("/data", ct); // No IResilientExecutor here
}

Configuration

  • Nested under service options (recommended) – resilience config lives in a Resilience subsection of your options (e.g. TwilioOptions:Resilience). Use AddLyoResiliencePipelinesFromOptions("TwilioOptions").
  • Standalone section – use AddLyoResiliencePipelines("Lyo:ResiliencePipelines") or any custom section path.

Strategy subsections

  • MaxRetryAttempts (int, default 3)
  • Delay (TimeSpan, e.g. "00:00:02")
  • MaxDelay (TimeSpan)
  • BackoffType ("Constant" | "Linear" | "Exponential")
  • UseJitter (bool)

Choosing resilience: actions vs HttpClient

Apply resilience at one level only to avoid exponential retries:

Use case Use this Do NOT
HTTP calls AddLyoResilienceHandler on the HttpClient IResilientExecutor around code that uses that HttpClient
Non-HTTP (DB, SDK, file I/O) IResilientExecutor

Wrapping HttpClient-using code with IResilientExecutor when that HttpClient already has AddLyoResilienceHandler causes nested resilience: each outer retry can trigger multiple inner retries, leading to exponential retry counts.

Resilience for actions

Use IResilientExecutor for work that does not go through HttpClient (e.g. database calls, SDKs, file I/O): Or use ResiliencePipelineProvider<string> directly:

Resilience for HttpClient

Use AddLyoResilienceHandler so resilience is applied at the HttpClient level. Call the client directly; do not wrap those calls with IResilientExecutor: The pipeline applies retry, timeout, and circuit breaker to each HTTP request (exception-based; retries on HttpRequestException, TimeoutException, etc.).

Metrics

When IMetrics is registered (e.g. via AddLyoMetrics), the library records:

Metric Type Description
lyo.resilience.retry Counter Each retry attempt (tag: pipeline)
lyo.resilience.timeout Counter Each timeout
lyo.resilience.circuit_breaker.opened Counter Circuit breaker opened
lyo.resilience.circuit_breaker.closed Counter Circuit breaker closed
lyo.resilience.circuit_breaker.half_opened Counter Circuit breaker half-opened
lyo.resilience.execution.duration Timing Execution duration
lyo.resilience.execution.success Counter Successful executions
lyo.resilience.execution.failure Counter Failed executions
lyo.resilience.execution.error Error Exceptions

All metrics include a pipeline tag with the pipeline name.

Logging

  • Retry: Warning on each retry with attempt number and delay
  • Timeout: Warning when an operation times out
  • CircuitBreaker: Warning when opened; Info when closed or half-opened

Dependencies

Generated from ProjectReference / PackageReference (same model as docs/Lyo.ProjectGraph.html).

  • Lyo.Exceptions — (direct, lyo)
  • Lyo.Metrics — (direct, lyo)
  • Microsoft.Extensions.Configuration.Binder 10.0.5 — (direct, microsoft)
  • Microsoft.Extensions.Http 10.0.5 — (direct, microsoft)
  • Polly 8.7.0 — (direct, third-party)
  • Polly.Extensions 8.7.0 — (direct, third-party)
  • Microsoft.Extensions.DependencyInjection.Abstractions 10.0.5 — (transitive, microsoft)
  • Microsoft.Extensions.Options.ConfigurationExtensions 10.0.5 — (transitive, microsoft)
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.2 0 8/19/2026
1.0.1 37 8/18/2026
1.0.0 51 8/16/2026