Created
November 12, 2018 23:00
-
-
Save sangheestyle/b022df1d9da81861d03ef6e7009b5b69 to your computer and use it in GitHub Desktop.
An example for using httpclientfactory
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<Project Sdk="Microsoft.NET.Sdk"> | |
<PropertyGroup> | |
<OutputType>Exe</OutputType> | |
<TargetFramework>netcoreapp2.1</TargetFramework> | |
</PropertyGroup> | |
<ItemGroup> | |
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.6" /> | |
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.1.1" /> | |
<PackageReference Include="Microsoft.Extensions.Http" Version="2.1.1" /> | |
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="2.1.1" /> | |
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.1.1" /> | |
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.1.1" /> | |
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" /> | |
<PackageReference Include="Polly" Version="6.1.1" /> | |
<PackageReference Include="Polly.Extensions.Http" Version="2.0.1" /> | |
</ItemGroup> | |
</Project> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright (c) .NET Foundation. All rights reserved. | |
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | |
using System; | |
using System.Net.Http; | |
using System.Threading; | |
using System.Threading.Tasks; | |
using Microsoft.Extensions.DependencyInjection; | |
using Microsoft.Extensions.Logging; | |
using Newtonsoft.Json.Linq; | |
using Polly; | |
namespace HttpClientFactorySample | |
{ | |
public class Program | |
{ | |
public static void Main(string[] args) => Run().GetAwaiter().GetResult(); | |
public static async Task Run() | |
{ | |
var serviceCollection = new ServiceCollection(); | |
serviceCollection.AddLogging(b => | |
{ | |
b.AddFilter((category, level) => true); // Spam the world with logs. | |
// Add console logger so we can see all the logging produced by the client by default. | |
b.AddConsole(c => c.IncludeScopes = true); | |
}); | |
Configure(serviceCollection); | |
var services = serviceCollection.BuildServiceProvider(); | |
Console.WriteLine("Creating a client..."); | |
var github = services.GetRequiredService<GitHubClient>(); | |
Console.WriteLine("Sending a request..."); | |
var response = await github.GetJson(); | |
var data = await response.Content.ReadAsAsync<JObject>(); | |
Console.WriteLine("Response data:"); | |
Console.WriteLine(data); | |
Console.WriteLine("Press the ANY key to exit..."); | |
Console.ReadKey(); | |
} | |
public static void Configure(IServiceCollection services) | |
{ | |
services.AddSingleton<HttpClientSettings>(); | |
var registry = services.AddPolicyRegistry(); | |
var timeout = Policy.TimeoutAsync<HttpResponseMessage>(TimeSpan.FromSeconds(10)); | |
var longTimeout = Policy.TimeoutAsync<HttpResponseMessage>(TimeSpan.FromSeconds(30)); | |
registry.Add("regular", timeout); | |
registry.Add("long", longTimeout); | |
services.AddHttpClient<GitHubClient>() | |
// Build a totally custom policy using any criteria | |
.AddPolicyHandler(Policy.TimeoutAsync<HttpResponseMessage>(TimeSpan.FromSeconds(10))) | |
// Use a specific named policy from the registry. Simplest way, policy is cached for the | |
// lifetime of the handler. | |
.AddPolicyHandlerFromRegistry("regular") | |
// Run some code to select a policy based on the request | |
.AddPolicyHandler((request) => | |
{ | |
return request.Method == HttpMethod.Get ? timeout : longTimeout; | |
}) | |
// Run some code to select a policy from the registry based on the request | |
.AddPolicyHandlerFromRegistry((reg, request) => | |
{ | |
return request.Method == HttpMethod.Get ? | |
reg.Get<IAsyncPolicy<HttpResponseMessage>>("regular") : | |
reg.Get<IAsyncPolicy<HttpResponseMessage>>("long"); | |
}) | |
// Build a policy that will handle exceptions, 408s, and 500s from the remote server | |
.AddTransientHttpErrorPolicy(p => p.RetryAsync()) | |
.AddHttpMessageHandler(() => new RetryHandler()); // Retry requests to github using our retry handler | |
} | |
private class GitHubClient | |
{ | |
public GitHubClient(HttpClient httpClient, HttpClientSettings httpClientSettings) | |
{ | |
httpClient.DefaultRequestHeaders.Add("Authorization", httpClientSettings.BearerToken); | |
httpClient.BaseAddress = new Uri("https://api.github.com/"); | |
httpClient.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json"); // GitHub API versioning | |
httpClient.DefaultRequestHeaders.Add("User-Agent", "HttpClientFactory-Sample"); // GitHub requires a user-agent | |
HttpClient = httpClient; | |
} | |
public HttpClient HttpClient { get; } | |
// Gets the list of services on github. | |
public async Task<HttpResponseMessage> GetJson() | |
{ | |
var request = new HttpRequestMessage(HttpMethod.Get, "/"); | |
var response = await HttpClient.SendAsync(request).ConfigureAwait(false); | |
response.EnsureSuccessStatusCode(); | |
return response; | |
} | |
} | |
private class RetryHandler : DelegatingHandler | |
{ | |
public int RetryCount { get; set; } = 5; | |
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) | |
{ | |
for (var i = 0; i < RetryCount; i++) | |
{ | |
try | |
{ | |
return await base.SendAsync(request, cancellationToken); | |
} | |
catch (HttpRequestException) when (i == RetryCount - 1) | |
{ | |
throw; | |
} | |
catch (HttpRequestException) | |
{ | |
// Retry | |
await Task.Delay(TimeSpan.FromMilliseconds(50)); | |
} | |
} | |
// Unreachable. | |
throw null; | |
} | |
} | |
private class HttpClientSettings | |
{ | |
public string BearerToken { get; set; } | |
public HttpClientSettings() | |
{ | |
BearerToken = "AAA"; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://stackoverflow.com/questions/51358870/configure-httpclientfactory-to-use-data-from-the-current-request-context