【问题标题】:Static HttpClient needs a URI from app.settings静态 HttpClient 需要来自 app.settings 的 URI
【发布时间】:2021-07-29 11:52:33
【问题描述】:

我的情况类似于下面的代码。鉴于在类的实例化发生时静态 HttpClient 属性已经存在,我无法注入 IConfiguration 或 IOptions,如何从 app.settings 获取代理 URI?

public class SomeApiClient : ISomeApiClient
{
    private static readonly HttpClientHandler ProxyClientHandler = new HttpClientHandler
    {
        Proxy = new WebProxy("http://serviceproxy.com"), //TODO Fetch from settings
        UseProxy = true,
    };

    //HttpClient is disposable but should be used liked this
    //(https://docs.microsoft.com/en-us/azure/architecture/antipatterns/improper-instantiation/#how-to-fix-improper-instantiation-antipattern)
    private static readonly HttpClient RestClient = new HttpClient(ProxyClientHandler);

    //The rest of the non-static class goes here...
}

【问题讨论】:

  • ProxyClientHandler.Proxy 有一个setter 为什么不改变Constructor?
  • 在构造函数中设置代理属性确实有效,但我认为“类型化客户端”是我正在寻找的。非常感谢你们的回复...

标签: c# .net-core configuration httpclient


【解决方案1】:

好的,所以实现最终是这样的:

        private static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .UseWindowsService()
            .ConfigureServices((hostContext, services) =>
            {
                services.AddHttpClient<IApiClient, ApiClient>().ConfigurePrimaryHttpMessageHandler(() =>
                {
                    var serviceProxy = new ServiceProxy();
                    hostContext.Configuration.GetSection("ServiceProxy").Bind(serviceProxy);

                    var handler = new HttpClientHandler
                    {
                        Proxy = new WebProxy(serviceProxy.Uri),
                        UseProxy = true,
                    };

                    return handler;
                });
                services.AddOptions();
                services.Configure<PollingIntervals>(hostContext.Configuration.GetSection("PollingIntervals"));
                services.AddHostedService<DownloadWorker>();
                services.AddHostedService<ArchiveWorker>();

                ConfigureDependencyInjection(services);
            });

“打字客户端”是这样的:

public class ApiClient : IApiClient
{
    private readonly IConfiguration config;
    private readonly ILogger<ApiClient> logger;
    private readonly HttpClient httpClient;


    public ApiClient(
        HttpClient httpClient,
        IConfiguration config,
        ILogger<ApiClient> logger)
    {
        this.config = config;
        this.logger = logger;
        this.httpClient = httpClient;
        this.httpClient.DefaultRequestHeaders.Clear();
        this.httpClient.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
    }

有趣的是,我现在得到了大量关于我以前没有得到的实际 HTTP 请求的日志记录。我添加了日志过滤器来调整它:

            .ConfigureLogging(logging =>
            {
                //Added these filters to stop seeing too many details about Http requests/responses
                logging.AddFilter("System.Net.Http.HttpClient.IApiClient.ClientHandler", LogLevel.Warning);
                logging.AddFilter("System.Net.Http.HttpClient.IApiClient.LogicalHandler", LogLevel.Warning);
            });

【讨论】:

    猜你喜欢
    • 2019-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-26
    相关资源
    最近更新 更多