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 thePolly.Extensions package to your project:
Basic Usage
Afterwards, you can use theAddResiliencePipeline(...) 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 forResiliencePipelineRegistry<string>.
string is inferred since the pipeline was defined using the “my-key” value.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 ofResiliencePipeline or ResiliencePipeline<T> using keyed services.
To begin, define your resilience pipeline:
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 theAddResiliencePipelines() 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.
Dynamic Reloads
Dynamic reloading is a feature of the pipeline registry that is also surfaced when using theAddResiliencePipeline(...) 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.
- The callback re-executes.
- The previous pipeline is discarded.
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:Complex Pipeline Keys
TheAddResiliencePipeline(...) 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:
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:
- We assigned the
PipelineNameComparerinstance to theBuilderComparerproperty. This action changes the default registry behavior, ensuring that only thePipelineNameis used to find the associated builder. - We used the
InstanceNameFormatterdelegate to represent theMyPipelineKeyas an instance name for telemetry purposes, keeping the instance name as it is. - Likewise, the
BuilderNameFormatterdelegate represents theMyPipelineKeyas a builder name in telemetry.
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
DO use another overload of Reasoning: This approach uses the already built
AddResiliencePipeline() which allows access to IServiceProvider:ServiceProvider and uses the same instance before every retry attempts.