Integrating Polly resilience policies with HttpClientFactory in ASP.NET Core allows you to build fault-tolerant HTTP clients capable of handling transient network failures, service outages, and slow responses seamlessly.
Prerequisites
To use Polly with HttpClientFactory, install the official Microsoft integration package via NuGet:
dotnet add package Microsoft.Extensions.Http.Polly
1. Defining Resilience Policies
Polly provides various policy types such as Retry, Circuit Breaker, and 00Timeout. Using the HttpPolicyExtensions helper class, you can easily target transient HTTP errors (5xx status codes and 408 Request Timeout, or HttpRequestException).
Defining a Retry Policy with Exponential Backoff
using Polly;
using Polly.Extensions.Http;
using System;
using System.Net.Http;
public static class PollyPolicies
{
public static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy()
{
return HttpPolicyExtensions
.HandleTransientHttpError()
.WaitAndRetryAsync(3, retryAttempt =>
TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));
}
}
Defining a Circuit Breaker Policy
public static IAsyncPolicy<HttpResponseMessage> GetCircuitBreakerPolicy()
{
return HttpPolicyExtensions
.HandleTransientHttpError()
.CircuitBreakerAsync(5, TimeSpan.FromSeconds(30));
}
2. Registering Policies with HttpClientFactory
In your Program.cs file, register your named or typed HTTP client using AddHttpClient and attach the resilience policies using AddPolicyHandler.
var builder = WebApplication.CreateBuilder(args);
// Register HttpClient with Polly Retry Policy
builder.Services.AddHttpClient("ExternalApiClient", client =>
{
client.BaseAddress = new Uri("https://api.example.com/");
client.DefaultRequestHeaders.Add("Accept", "application/json");
})
.AddPolicyHandler(PollyPolicies.GetRetryPolicy())
.AddPolicyHandler(PollyPolicies.GetCircuitBreakerPolicy());
var app = builder.Build();
3. Consuming the HttpClient
Inject IHttpClientFactory into your services or controllers and create client instances normally. The Polly policies will execute automatically around each request execution.
public class WeatherService
{
private readonly IHttpClientFactory _httpClientFactory;
public WeatherService(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}
public async Task<string> GetWeatherDataAsync()
{
var client = _httpClientFactory.CreateClient("ExternalApiClient");
var response = await client.GetAsync("weather");
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
}
Conclusion
By coupling IHttpClientFactory with Polly policies, you centralize transient error handling, enhance system dependability, and keep HTTP service interaction logic clean and maintainable.