Caching in Polly and the HttpClientFactory
Full source code here.
Want to learn more about Polly? Check out my Pluralsight course on it.
Polly allows you to cache a response for reuse by a subsequent request, it supports both local an distributed caches, full information can be found here https://github.com/App-vNext/Polly/wiki/Cache.
HttpClientFactory lets you define polices in
startup.cs and apply them to
HttpClient requests anywhere in your application. With most policies this makes it easier for you to apply a policy to a request, but with the cache policy it complicates matters.
With the release of
HttpClientFactory there are now two ways to use the cache policy, one taking advantage of
HttpClientFactory to apply the policy to requests, and the other bypassing it when executing requests.
Caching with the cache policy inside the HttpClientFactory
First let’s look at how to use the Cache Policy using
PolicySelector method on the
HttpClientFactory to apply the policy to the request, see this post for more info.
If you are working in Polly V6+ add
Polly.Caching.Memory package to your project, this is important, don’t add
Polly.Caching.MemoryCache that is for Polly V5.9 and earlier, and many an hour was lost figuring that out.
Startup.cs add the following to the
ConfigureServices method -
This sets up the in memory cache and policy registry, adding both to
ServicesCollection. The cache policy is not added here, instead it is added in the
Configure(..) method (thanks Andrew Lock for reminding me about this).
Next, add the
HttpClientFactory and a method to pick the appropriate policy from the registry.
Configure(..) I setup the cache policy. The registry and cache provider are passed via dependency injection.
In the controller I have a constructor that takes one argument, the
In the action method I get the
HttpClient from the
HttpClientFactory and specify the remote endpoint I want to call, but now I can’t use usual
httpClient.GetAsync(..) because I can’t pass it a cache context key (i.e. the name of where I look for previously cached responses and store new responses).
Instead I build a
HttpRequestMessage, specifying the
Uri and using a Polly extension method I set the cache context.
This approach feels a bit awkward and not many people use the
HttpRequestMessage to send requests to remote services.
Caching with the cache policy outside the HttpClientFactory
An alternative to the above is to add the cache to the registry, but not add the registry to the
In this case the adding the
HttpClientFactory to the services collection changes slightly -
In the controller we now pass in the registry as
HttpClientFactory as constructor arguments.
There are changes inside the action method also -
httpClient is retrieved from the
HttpClientFactory as before, but now the
cachePolicy is taken from the policy registry, the
Context is defined and then we use the
cachePolicy.ExecuteAsync(..) method to make call the
The other way
You might have noticed that there is another way of using the cache policy. You could use the
HttpClientFactory and a
PolicySelector method to apply most policies to your
HttpClient requests, but not for the cache policy. I wouldn’t do this, it will confuse everyone.
The outcome of both is the same, I think the first approach is better, even though the call to the
httpClient is a little more convoluted, it will be more consistent with how you call other policies in your application, there is also a chance the Polly team will add an extension method to make the use of
HttpRequestMessage transparent to us developers.
Full source code here.
- Selectively Caching a HttpResponseMessage with Polly - caching series 1/3
- Selectively Caching Values Inside HttpResponseMessage with Polly – caching series 3/3
- Polly, HttpClientFactory and the Policy Registry in a console application
- Caching Values Inside HttpResponseMessage with Polly – caching series 2/3
- How to use HttpClientFactory Inside Program.cs