.NET Core AddHttpClient动态配置

时间:2019-07-02 10:42:13

标签: c# dependency-injection .net-core factory-pattern

我正在使用AddHttpClient扩展名来配置个人HttpClient中使用的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);
        });
    }

如果我在服务中注入IRestClient,一切都很好,但是问题是当我想使用IRestClient动态创建RestClientFactory以使用自定义配置时(默认DI绑定没有提供该配置) (用于IRestClientSettings)。我该如何实现?

IRestClientSettings只是自定义设置以及ConfigureHttp方法,用户可以在其中定义自定义HttpClient设置。

1 个答案:

答案 0 :(得分:0)

我总是通过IRestClient创建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()
            );
        }
    }

和DI配置

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;
    }