Skip to content

Latest commit

 

History

History
57 lines (40 loc) · 1.99 KB

File metadata and controls

57 lines (40 loc) · 1.99 KB

HCR082

Avoid per-request creation of resilience pipelines.

Why

ResiliencePipelineBuilder.Build() creates a reusable Polly pipeline. Building it inside a request path repeats configuration work and allocations for every request instead of reusing a singleton, typed-client, or cached pipeline configured at startup.

Bad

public sealed class PaymentsController
{
    public void Post()
    {
        var pipeline = new ResiliencePipelineBuilder()
            .AddRetry()
            .Build();

        pipeline.Execute();
    }
}

Better

public sealed class PaymentsClient
{
    private static readonly ResiliencePipeline Pipeline =
        new ResiliencePipelineBuilder()
            .AddRetry()
            .Build();

    public void Send()
    {
        Pipeline.Execute();
    }
}

Prefer configuring outbound HTTP resilience through IHttpClientFactory and Microsoft.Extensions.Http.Resilience when the pipeline is specifically for HttpClient.

Current Detection

The implementation reports Polly.ResiliencePipelineBuilder.Build() calls inside obvious request paths. Request-path evidence includes controller/service-style type suffixes such as Controller, Endpoint, Handler, Worker, Service, Repository, and Job, plus Minimal API endpoint lambdas such as app.MapPost(..., () => ...).

It recognizes direct builder construction, fluent builder chains, and visible builder locals that have not been reassigned. Static field initializers, startup/configuration types without request-path evidence, obvious test contexts, and resolved custom builder lookalikes are skipped.

Suppression

Suppress only when the request path intentionally builds a short-lived pipeline from request-specific configuration and the allocation/throughput cost is acceptable.

References