.NET Core AddHttpClient Dynamic Configuration

Viewed 3330

I'm using AddHttpClient extension to configure HttpClient used in my personal RestClient.

    public class RestClient : IRestClient
    {
        public RestClient(IRestClientSettings settings, HttpClient httpClient)
        {
            ...
        }
    }

    public class RestClientFactory
    {
        public IRestClient Create(IRestClientSettings settings)
        {
            // how to create IRestClient with above configuration??
        }
    }

    public static IServiceCollection AddServices(this IServiceCollection services)
    {
        services.AddHttpClient<IRestClient, RestClient>((provider, client) =>
        {
            // problem, this is always same binded instance, 
            // not the one provided in RestClientFactory
            var settings = provider.GetService<IRestClientSettings>(); 
            settings.ConfigureHttp(provider, client);
        });
    }

Everything is fine if I inject IRestClient in my services but the problem is when I want to dynamically create IRestClient using RestClientFactory to use custom configuration (not one provided by default DI binding for IRestClientSettings). How can I achieve that?

IRestClientSettings are just custom settings along with ConfigureHttp method where user can define custom HttpClient settings.

1 Answers

I've ended up using simplest solution by always creating IRestClient via IRestClientFactory.

public class RestClientFactory : IRestClientFactory
    {
        protected IHttpClientFactory HttpClientFactory { get; }
        protected IServiceProvider ServiceProvider { get; }

        public RestClientFactory(IHttpClientFactory httpClientFactory, IServiceProvider serviceProvider)
        {
            HttpClientFactory = httpClientFactory;
            ServiceProvider = serviceProvider;
        }

        public IRestClient Create()
        {
            return Create(ServiceProvider.GetService<IRestClientSettings>());
        }

        public IRestClient Create(IRestClientSettings settings)
        {
            return new RestClient(
                settings,
                HttpClientFactory.CreateClient()
            );
        }
    }

And DI configuration

public static IServiceCollection AddDotaClientService(this IServiceCollection services)
    {
        services.AddTransient<IRestClient>(provider =>
        {
            var clientFactory = provider.GetService<IRestClientFactory>();
            return clientFactory.Create();
        });

        services.AddSingleton<IRestClientFactory, RestClientFactory>();

        return services;
    }
Related