Skip to main content
Starting with version 8, Polly provides features that make the integration of Polly with the .NET IServiceCollection Dependency Injection (DI) container more streamlined. This is a thin layer atop the resilience pipeline registry which manages resilience pipelines.

Installation

To use the DI functionality, add the Polly.Extensions package to your project:

Basic Usage

Afterwards, you can use the AddResiliencePipeline(...) extension method to set up your pipeline:
The AddResiliencePipeline extension method also registers the following services into the DI container:
  • ResiliencePipelineRegistry<string>: Allows adding and retrieving resilience pipelines.
  • ResiliencePipelineProvider<string>: Allows retrieving resilience pipelines.
  • IOptions<ResiliencePipelineRegistryOptions<string>>: Options for ResiliencePipelineRegistry<string>.
The generic string is inferred since the pipeline was defined using the “my-key” value.
If you only need the registry without defining a pipeline, use the AddResiliencePipelineRegistry(...) method.

Generic Resilience Pipelines

You can also define generic resilience pipelines (ResiliencePipeline<T>), as demonstrated below:

Keyed Services

.NET 8 introduced support for keyed services. Starting from version 8.3.0, Polly supports the retrieval of ResiliencePipeline or ResiliencePipeline<T> using keyed services. To begin, define your resilience pipeline:
Following the definition above, you can resolve the resilience pipelines using keyed services as shown in the example below:
The resilience pipelines are registered in the DI container as transient services. This enables the resolution of multiple instances of ResiliencePipeline when complex pipeline keys are used. The resilience pipeline is retrieved and registered using ResiliencePipelineProvider that is responsible for lifetime management of resilience pipelines.

Deferred Addition of Pipelines

If you want to use a key for a resilience pipeline that may not be available immediately you can use the AddResiliencePipelines() method to defer adding them until just prior to the ResiliencePipelineProvider<TKey> is instantiated by the DI container, allowing the IServiceProvider to be used if required.
The AddResiliencePipelines method does not support keyed services. To enable the resolution of a resilience pipeline using keyed services, you should use the AddResiliencePipeline extension method, which adds a single resilience pipeline and registers it into the keyed services.

Dynamic Reloads

Dynamic reloading is a feature of the pipeline registry that is also surfaced when using the AddResiliencePipeline(...) extension method. Use an overload that provides access to AddResiliencePipelineContext:
1

EnableReloads activates dynamic reloading

EnableReloads<T>(...) activates the dynamic reloading of my-pipeline.
2

Fetch options using context

RetryStrategyOptions are fetched using context.GetOptions(...) utility method.
3

Add strategy

A retry strategy is added.
During a reload:
  • The callback re-executes.
  • The previous pipeline is discarded.
If an error occurs during reloading, the old pipeline remains, and dynamic reloading stops.

Resource Disposal

Like dynamic reloading, the pipeline registry’s resource disposal feature lets you register callbacks. These callbacks run when the pipeline is discarded, reloaded, or the registry is disposed at application shutdown. See the example below:
This feature ensures that resources are properly disposed when a pipeline reloads, discarding the old version.

Complex Pipeline Keys

The AddResiliencePipeline(...) method supports complex pipeline keys. This capability allows you to define the structure of your pipeline and dynamically resolve and cache multiple instances of the pipeline with different keys. Start by defining your complex key:
Next, register your pipeline:
The “my-pipeline” pipeline is now registered. Note that the InstanceName is an empty string. While we’re registering the builder action for a specific pipeline, the InstanceName parameter isn’t used during the pipeline’s registration. Some further modifications are required for this to function. Introduce the PipelineNameComparer:
Then, configure the registry behavior:
Let’s summarize our actions:
  • We assigned the PipelineNameComparer instance to the BuilderComparer property. This action changes the default registry behavior, ensuring that only the PipelineName is used to find the associated builder.
  • We used the InstanceNameFormatter delegate to represent the MyPipelineKey as an instance name for telemetry purposes, keeping the instance name as it is.
  • Likewise, the BuilderNameFormatter delegate represents the MyPipelineKey as a builder name in telemetry.
Finally, use the ResiliencePipelineProvider<MyPipelineKey> to dynamically create and cache multiple instances of the same pipeline:

Anti-patterns

Over the years, many developers have used Polly in various ways. Some of these recurring patterns may not be ideal. The sections below highlight anti-patterns to avoid.

Accessing the IServiceCollection instead of IServiceProvider

DON’T capture IServiceCollection inside AddResiliencePipeline():
Reasoning: This approach builds a new ServiceProvider before each retry attempt unnecessarily.
DO use another overload of AddResiliencePipeline() which allows access to IServiceProvider:
Reasoning: This approach uses the already built ServiceProvider and uses the same instance before every retry attempts.