Full source code available here.
This post continues to build on the two previous on using Polly with Blazor. The first was a simple example of using a Wait and Retry while updating the display as the policy retried, the second did the same but made use of the Polly Context. The Polly Context is something I have not made a lot of use of in the past, but I have a feeling that it will be very helpful with Blazor applications.
I’m keeping the examples similar, deliberately changing a single thing in each. In this post I will define the Wait and Retry Policy in the Startup
, add it to the service collection and inject it into the Razor page.
One big difference to note is that I can no longer update the display from inside the OnRetry
delegate of the Policy. Gone is the call to InvokeAsync(StateHasChanged)
because this is dependent on the the ComponentBase
.
In Startup.cs
add the following, it defines the Wait and Retry policy, and its OnRetry
delegate –
public void ConfigureServices(IServiceCollection services) { IAsyncPolicy<HttpResponseMessage> _httpRequestPolicy = Policy.HandleResult<HttpResponseMessage>( r => !r.IsSuccessStatusCode) .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(retryAttempt), onRetry: (response, retryDelay, retryCount, context) => { context["message"] = context["message"] + $"\nReceived: {response.Result.StatusCode}, retryCount: {retryCount}, delaying: {retryDelay.Seconds} seconds"; }); services.AddSingleton<IAsyncPolicy<HttpResponseMessage>>(_httpRequestPolicy); // snip...
In the Razor section of the Index.razor
page add this –
@inject IAsyncPolicy<HttpResponseMessage> _httpRequestPolicy
The policy will now be injected into the Razor page.
Using it is simple, see line 16 below –
@code { HttpClient httpClient = new HttpClient() { BaseAddress = new Uri("http://localhost:5000") }; private string status; private Context context = new Polly.Context("", new Dictionary<string, object>() {{"message",""}}); private string responseCode; private string number; private async Task CallRemoteServiceAsync() { status = "Calling remote service..."; string requestEndpoint = "faulty/"; HttpResponseMessage httpResponse = await _httpRequestPolicy.ExecuteAsync(ctx => httpClient.GetAsync(requestEndpoint), context); responseCode = httpResponse.StatusCode.ToString(); number = await httpResponse.Content.ReadAsStringAsync(); status = "Finished"; } }
Instead of injecting a Polly Policy you could inject a Polly Registry with more than one policy. I have written about the registry a few times on this blog.
Full source code available here.