.NetCore Flurl.Http 4.0.0 以上管理客户端

参考原文地址:Managing Clients - Flurl

管理客户端

Flurl.Http 构建在堆栈之上System.Net.Http。如果您熟悉HttpClient,那么您可能听说过这个建议:不要为每个请求创建一个新客户端;重复使用它们,否则将面临后果。AFlurlClient包装单个HttpClient并绑定到相同的生命周期,因此建议是相似的。

无客户端使用

如果您不想FlurlClient显式管理实例,则不需要;Flurl 会为你做这件事。事实上,在该网站的大多数示例中,客户端都明显缺席:

cs 复制代码
var result = await "https://some-api.com".GetJsonAsync<T>();

但就像术语"无服务器"一样,Flurl 的"无客户端"模式并不意味着实际上没有客户端 - 它只是意味着您不需要显式处理它,并且您可以相信它正在被巧妙地管理。为此,Furll 使用 缓存并重用客户端实例FlurlHttp.Clients,这是 的全局单例实例IFlurlClientCache。客户端可以在启动时预先配置:

cs 复制代码
FlurlHttp.ConfigureClientForUrl("https://some-api.com")
    .WithSettings(settings => ...)
    .WithHeaders(...)

注意:*配置*WithSettings部分详细介绍了其他相关方法。

使用无客户端模式,对同一主机(或更准确地说,方案/主机/端口的相同组合)的所有调用都将重用同一客户端。任何客户端级别的配置(例如默认标头)都将伴随对该主机的所有调用。如果需要,您可以更改此缓存策略。例如,也许您希望对服务的每个版本使用不同的客户端,可通过自定义请求标头进行识别:

cs 复制代码
FlurlHttp.UseClientCachingStrategy(request =>
    // get the default host-based key by invoking the default caching strategy:
    var name = FlurlHttp.BuildClientNameByHost(request);
    // append the service version from a custom request header, if it exists:
    if (request.Headers.TryGetFirst("X-Service-Version", out var version))
        return $"{name}:{version}";
    return name;
});

使用自定义缓存策略时,请确保在任何调用之前UseClientCachingStrategy调用.ConfigureClientForUrl

显式用法

许多开发人员,尤其是那些想要严格遵守依赖注入原则的开发人员,可能会对管理客户端的全局静态上下文的存在感到厌烦,认为这可能导致更紧密的耦合并使系统更难以测试。由于这些原因,Flurl 支持另一种使用模式,其中客户端管理是明确的(并且几乎同样简单):

cs 复制代码
var client = new FlurlClient("https://some-api.com") // a base URL is optional
    .WithSettings(settings => ...)
    .WithHeaders(...);

var result = await client.Request("path").GetJsonAsync<T>();

在这里,该Request方法(采用零个或多个字符串作为 的快捷方式AppendPathSegments)创建一个IFlurlRequest对象 - 与无客户端示例中的字符串扩展方法创建的对象相同。因此,在任何一种情况下都可以使用所有相同的流畅、可链接的方法。

使用依赖注入

为了使 Flurl 完全对 DI 友好,仍然存在一个问题:我们不想new从我们的服务类内部启动该客户端;我们想注入一些东西。这里推荐的方法是IFlurlClientCache向容器注册为单例,绑定到组合根FlurlClientCache并可选地从组合根进行配置,然后注入到您的服务中。IFlurlClientCache支持命名客户端,这在概念上与 IHttpClientFactory 的命名客户端非常相似。

cs 复制代码
// at service registration:
services.AddSingleton<IFlurlClientCache>(sp => new FlurlClientCache()
    .Add("MyCli", "https://some-api.com"));

// in service class:
public class MyService : IMyService
{
    private readonly IFlurlClient _flurlCli;

    public MyService(IFlurlClientCache clients) {
        _flurlCli = clients.Get("MyCli");
    }
}

与无客户端模式非常相似,所有客户端都由单个IFlurlClientCache. 但该单例现在由 IoC 容器而不是静态对象控制FlurlHttp。赢!

在上面的示例中,clients.Get如果尚未创建指定的客户端(在本示例中是在服务注册时),则会引发异常。但在启动时预先创建客户端并不是严格要求的 -GetOrAdd可以改为使用:

cs 复制代码
_flurlCli = clients.GetOrAdd("MyCli", "https://some-api.com");

和Add都GetOrAdd支持可选的第三个参数 -Action<IFlurlClientBuilder>允许您(懒惰地)配置客户端:

cs 复制代码
.Add("MyCli", "https://some-api.com", builder => builder
    .WithSettings(settings => ...)
    .WithHeaders(...)

翻译的可能不够准确,请见谅,请阅读原文:Managing Clients - Flurl,希望本文对你有帮助。

相关推荐
lixww.cn1 天前
ASP.NET Core与配置系统的集成
.netcore
张3蜂3 天前
如何利用Docker和.NET Core实现环境一致性、简化依赖管理、快速部署与扩展,同时提高资源利用率、确保安全性和生态系统支持
docker·容器·.netcore
lixww.cn3 天前
.NET Core 中依赖注入的使用
.netcore
醉の虾4 天前
Vue3 结合 .NetCore WebApi 前后端分离跨域请求简易实例
前端·vue.js·.netcore
时光追逐者4 天前
一组开源、免费、Metro风格的 WPF UI 控件库
ui·开源·c#·.net·wpf·.netcore·微软技术
时光追逐者5 天前
C#/.NET/.NET Core技术前沿周刊 | 第 23 期(2025年1.20-1.26)
microsoft·c#·.net·.netcore·微软技术
lixww.cn5 天前
.NET Core缓存
缓存·.netcore
lixww.cn6 天前
ASP.NET Core MVC
c#·mvc·.netcore
亦世凡华、6 天前
从CRUD到高级功能:EF Core在.NET Core中全面应用(四)
经验分享·.netcore·ef core·表达式树
lixww.cn6 天前
ASP.NET Core WebAPI的异步及返回值
.netcore