ASP.Net Core 2.1中的Flurl客户端生命周期和IHttpClientFactory

15

Flurl建议使用单例客户端模式:

HttpClient旨在在应用程序生命周期内实例化一次并重复使用。特别是在服务器应用程序中,每个请求创建一个新的HttpClient实例将在重负载下耗尽可用套接字的数量。这将导致SocketException错误。

但自Asp.Net Core 2.1以来,Net Core 2.1有更新的HttpClient生命周期规则

当您使用HttpClientFactory请求HttpClient时,您确实每次都会获得新实例,这意味着我们不必担心它的状态变化。此HttpClient可以(也可能不)使用来自池中的现有HttpClientHandler,并因此使用现有的打开连接。

如何修改Flurl以在其内部使用IHttpClientFactory?我应该创建自定义的Flurl settings.HttpClientFactory,然后通过MS IHttpClientFactory创建HttpClient吗?


对于ASP .Net 2.1和Flurl 2.0,无法像Todd Menier建议的那样实例化FlurlClient。 - Rodrigo S. Teixeira
1
@RodrigoS.Teixeira 这在技术上是正确的,必须使用Flurl.Http 2.3.1中引入的构造函数来完成此操作,该版本于去年4月发布。有什么阻止你升级的因素吗? - Todd Menier
1个回答

19
首先,需要注意的是MS的新HttpClientFactory旨在与ASP.NET Core 2.1及其内置DI容器一起使用。如果您没有将FlurlClient注入到控制器或服务类中,而是像这样使用Flurl:
await url.GetJsonAsync();

如果你想要使用新的套接字池特性,那么实现Flurl's IHttpClientFactory去使用MS是不相关的。它没有适当的上下文来使用DI容器,你最终会退而求其次,使用服务定位,这是一种反模式。你想要利用的那些新的套接字池特性实际上存在于更低的层级上:System.Net.Http.SocketsHttpHandler。Flurl默认使用HttpClientHander作为其消息处理程序,但幸运的是,在.NET Core 2.1中,所有工作都已经被重写为默认延迟到SocketsHttpHandler。换句话说,如果你正在一个.NET Core 2.1应用程序中使用Flurl,你已经得到了MS一直在努力开发的所有新的套接字管理好处
如果你在ASP.NET Core 2.1应用程序中明确地使用FlurlClient,作为HttpClient的替代品,并希望注入到你的类中,同时利用MS的HttpClientFactory所提供的功能,我建议按照MS的规定在ConfigureServices中设置HttpClientFactory,当你需要一个FlurlClient实例时,使用带有HttpClient实例的构造函数。例如,当使用类型化客户端模式时,你的服务类可能如下所示:
public class MyService
{
    private readonly IFlurlClient _flurlClient;

    public MyService(HttpClient httpClient)
    {
        _flurlClient = new FlurlClient(httpClient);
    }
}

很抱歉挖掘这个非常古老的答案,但我想知道:鉴于您已经说过Flurl已经将套接字池和DNS查询的刷新委托给了BCL,那么DefaultHttpClientFactory在这里有什么可提供的呢?考虑到ServiceCollection.AddHttp()的繁重性,除非它在Flurl之上添加了大量价值,否则我不太愿意使用它。 - Nick Cox
1
@NickCox 这是个好问题。Flurl的HttpClientFactory非常专注于构造FlurlClient使用的HttpClient和HttpMessageHandler,而不关心缓存实例、重用套接字等。它只关注构造细节。如果您像上面的示例一样向FlurlClient构造函数提供了一个HttpClient,则根本不会使用它。只有在您没有提供时,FlurlClient才会在需要时(惰性地)调用它一次。 - Todd Menier

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接