首页 > 解决方案 > 对新 ihttpfactory 中 httpclient 的生命周期感到困惑

问题描述

从规范为单例的代码重构为httpclient新的代码,ihttpfactory我对以下代码的生命周期感到非常困惑httpClient

The typed client is registered as transient with DI. [打字客户]

这意味着我以前依赖的所有单例服务httpclient现在都将效仿[即暂时的]。我找不到有关此设计选择的支持文档?由于我们必须使所有依赖图瞬态化,现在这不会对性能造成伤害吗?

标签: c#httpclient.net-5ihttpclientfactory

解决方案


谷歌“键入的 httpclient 瞬态”是你的朋友:https ://www.stevejgordon.co.uk/ihttpclientfactory-patterns-using-typed-clients-from-singleton-services

简单地说,不是直接注入和使用类型化的 HttpClient,而是创建一个依赖于 IServiceProvider 的工厂,并使用一个方法使用该服务提供者返回一个类型化的 HttpClient 的实例,然后注入该工厂。然后,每次需要类型化 HttpClient 的实例时调用工厂的创建方法。服务提供商为您完成所有范围的管理。

换句话说,而不是以下内容:

services.AddHttpClient<IMyHttpClient, MyHttpClient>();
services.AddScoped<IDependsOnHttpClient, DependsOnHttpClient>();

...

public class DependsOnHttpClient : IDependsOnHttpClient
{
    private readonly IMyHttpClient _httpClient;

    public DependsOnHttpClient(IMyHttpClient httpClient)
        => _httpClient = httpClient;

    public async Task DoSomethingWithHttpClientAsync()
        => _httpClient.GetAsync("https://foo.bar");
}

你写:

services.AddHttpClient<IMyHttpClient, MyHttpClient>();
services.AddSingleton<IMyHttpClientFactory, MyHttpClientFactory>();
services.AddSingleton<IDependsOnHttpClient, DependsOnHttpClient>();

...

public class MyHttpClientFactory : IMyHttpClientFactory
{
    private readonly IServiceProvider _serviceProvider;

    public MyHttpClientFactory(IServiceProvider serviceProvider)
        => _serviceProvider = serviceProvider;

    public IMyHttpClient CreateClient()
        => _serviceProvider.GetRequiredService<IMyHttpClient>();
}

public class DependsOnHttpClient : IDependsOnHttpClient
{
    private readonly IMyHttpClientFactory _httpClientFactory;

    public DependsOnHttpClient(IMyHttpClientFactory httpClientFactory)
        => _httpClientFactory = httpClientFactory;

    public async Task DoSomethingWithHttpClientAsync()
    {
         var httpClient = _httpClientFactory.CreateClient();

         return await _httpClient.GetAsync("https://foo.bar");
    }
}

此时您可能想知道“编写所有这些代码与仅注入 IHttpClientFactory 并调用其方法相比,我能获得什么”,老实说,我不确定答案。也许使用 Roslyn 源生成器,我们将能够为它们生成类型化的 HttpClient 和工厂。


推荐阅读