'How to use HttpClientFactory with AutoRest generated client

AutoRest generated client don't have suitable constructor for use it with services.AddHttpClient() method. So how can we get around this?

Now we have public constructor with such signature.

public Client(ServiceClientCredentials credentials, HttpClient httpClient, bool disposeHttpClient) : this(httpClient, disposeHttpClient)

But becouse it have bool disposeHttpClient argument we can't use it direct within AddHttpClient() method to configure client service into DI. HttpClientFactory, to my deep regret, does not contain an override version of a method AddHttpClient with such a signature:

AddHttpClient<IClient>(Func<IServiceProvider, HttpClietn, IClient> configClient)


Solution 1:[1]

You'll need to use a named client, rather than a typed client, and then you'll need to register your AutoRest client using the factory overload.

services.AddHttpClient("MyAutoRestClient", c =>
{
    // configure your HttpClient instance
});

services.AddScoped<MyAutoRestClient>(p =>
{
    var httpClient = p.GetRequiredService<IHttpClientFactory>().GetClient("MyAutoRestClient");
    // get or create any other dependencies
    // set disposeHttpClient to false, since it's owned by the service collection
    return new MyAutoRestClient(credentials, httpClient, false);
});

Solution 2:[2]

There is one more way that we can achieve. We can inherit from generated class and define for DI and AddHttpClient() constructor. See code below.

public partial class MyAutoRestClientExtended: MyAutoRestClient
{
    public MyAutoRestClientExtended(HttpClient httpClient, IOptions<SomeOptions> options)
        : base(new EmptyServiceClientCredentials(), httpClient, false)
    {
        var optionsValue = options.Value ?? throw new ArgumentNullException(nameof(options));
        BaseUri = optionsValue .Url;
    }
}

Now we can use AddHttpClient() method for configure typed client via fluent builder with all its benefits like Polly policies and HttpHandler defining.

services.AddHttpClient<MyAutoRestClientExtended>()
                   .ConfigureHttpClient((sp, httpClient) =>
                   {                         
                       httpClient.Timeout = TimeSpan.FromSeconds(30);
                   })
                   .SetHandlerLifetime(TimeSpan.FromMinutes(5))
                   .ConfigurePrimaryHttpMessageHandler(x => new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate })
                   .AddHttpMessageHandler(sp => sp.GetService<AuthenticationHandlerFactory>().CreateAuthHandler())
                   .AddPolicyHandlerFromRegistry(PollyPolicyName.HttpRetry)
                   .AddPolicyHandlerFromRegistry(PollyPolicyName.HttpCircuitBreaker);

Finally, define singleton service for service contract usage.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Viswa