在ASP.NET Core中用HttpClient(六)——ASP.NET Core中使用HttpClientFactory

添加HttpClientFactory

为了能够在我们的应用程序中使用HttpClientFactory,必须安装 Microsoft.Extensions.Http。

Install-Package Microsoft.Extensions.Http -Version 5.0.0
然后,我们必须使用Program 类中通过AddHttpClient方法将IHttpClientFactory和其他服务添加到服务集合中:

复制代码
private static void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient();

//services.AddScoped<IHttpClientServiceImplementation, HttpClientCrudService>();
//services.AddScoped<IHttpClientServiceImplementation, HttpClientPatchService>();
//services.AddScoped<IHttpClientServiceImplementation, HttpClientStreamService>();
//services.AddScoped<IHttpClientServiceImplementation, HttpClientCancellationService>();

}
复制代码
我们很快就会用额外的配置来扩展这个方法。现在,让我们创建一个新的服务类,就像我们在前面的文章中所做的那样:

复制代码
public class HttpClientFactoryService : IHttpClientServiceImplementation
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly JsonSerializerOptions _options;

public HttpClientFactoryService(IHttpClientFactory httpClientFactory)
{
    _httpClientFactory = httpClientFactory;

    _options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
}

public async Task Execute()
{
    throw new NotImplementedException();
}

}
复制代码
为了能够在我们的HttpClientFactoryService类中使用HttpClientFactory,我们必须通过依赖注入来注入它。此外,我们还为JSON序列化配置选项。我们不想在这里添加取消逻辑,所以没有像上一篇文章中那样使用CancellationTokenSource。

现在,让我们添加一个新方法来从API中获取公司数据:

复制代码
private async Task GetCompaniesWithHttpClientFactory()
{
var httpClient = _httpClientFactory.CreateClient();

using (var response = await httpClient.GetAsync("https://localhost:5001/api/companies", HttpCompletionOption.ResponseHeadersRead))
{
    response.EnsureSuccessStatusCode();

    var stream = await response.Content.ReadAsStreamAsync();

    var companies = await JsonSerializer.DeserializeAsync<List<CompanyDto>>(stream, _options);
}

}
复制代码
在这段代码中,我们唯一不熟悉的部分是使用HttpClientFactory中的CreateClient方法来使用默认配置创建一个新的HttpClient。本系列前面的文章中已经解释了其他所有内容。另外,由于没有提供自定义配置,我们必须在GetAsync方法中使用完整的URI。

在此之后,我们可以修改Execute方法:

public async Task Execute(){ await GetCompaniesWithHttpClientFactory();}
同样,让我们在Program类中注册这个服务:

复制代码
private static void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient();

...
services.AddScoped<IHttpClientServiceImplementation, HttpClientFactoryService>();

}
复制代码
在新方法中放置断点并启动两个应用程序:

使用命名的HttpClient实例

在Program类中,我们使用AddHttpClient方法注册IHttpClientFactory,而不需要额外的配置。这意味着用CreateClient方法创建的每个HttpClient实例都将具有相同的配置。但通常,这是不够的,因为我们的客户端应用程序在与一个或多个api通信时经常需要不同的HttpClient实例。为了支持这一点,我们可以使用命名的HttpClient实例。

在之前的文章中,我们在每个服务中使用了相同的配置来设置基址、超时和清除默认请求头。现在,我们也可以这样做,但只有一个地方:

复制代码
private static void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient(“CompaniesClient”, config =>
{
config.BaseAddress = new Uri(“https://localhost:5001/api/”);
config.Timeout = new TimeSpan(0, 0, 30);
config.DefaultRequestHeaders.Clear();
});

...
services.AddScoped<IHttpClientServiceImplementation, HttpClientFactoryService>();

}
复制代码
通过这些修改,AddHttpClient方法将IHttpClientFactory添加到服务集合中,并配置一个已命名的HttpClient实例。我们为实例提供一个名称和一个默认配置。在此之后,可以在我们的新服务中修改方法:

复制代码
private async Task GetCompaniesWithHttpClientFactory()
{
var httpClient = _httpClientFactory.CreateClient(“CompaniesClient”);

using (var response = await httpClient.GetAsync("companies", HttpCompletionOption.ResponseHeadersRead))
{
    response.EnsureSuccessStatusCode();

    var stream = await response.Content.ReadAsStreamAsync();

    var companies = await JsonSerializer.DeserializeAsync<List<CompanyDto>>(stream, _options);
}

}
复制代码
我们将name参数传递给CreateClient方法,而且不必在GetAsync方法中使用完整的URI。由于使用的是客户机的名称,因此应用与此名称对应的配置。

一旦我们启动这两个应用程序,将得到和之前一样的结果:

使用类型化HttpClient实例

使用类型化实例,我们可以实现与命名实例相同的功能,但在注册过程中不必使用字符串——可以使用类型。首先在客户端应用程序中创建一个新的Clients文件夹,并在该文件夹中创建一个新的CompaniesClient类:

复制代码
public class CompaniesClient
{
public HttpClient Client { get; }

public CompaniesClient(HttpClient client)
{
    Client = client;

    Client.BaseAddress = new Uri("https://localhost:5001/api/");
    Client.Timeout = new TimeSpan(0, 0, 30);
    Client.DefaultRequestHeaders.Clear();
}

}
复制代码
这是我们使用默认配置的类型化客户端类,我们可以通过在ConfigureServices方法中再次调用AddHttpClient来在程序类中注册它:

services.AddHttpClient();
因此,我们使用的不是客户端的名称,而是客户端的类型。

现在,在我们的HttpClientFactoryService中,必须注入新的客户端:

复制代码
private readonly IHttpClientFactory _httpClientFactory;
private readonly CompaniesClient _companiesClient;
private readonly JsonSerializerOptions _options;

public HttpClientFactoryService(IHttpClientFactory httpClientFactory, CompaniesClient companiesClient)
{
_httpClientFactory = httpClientFactory;
_companiesClient = companiesClient;

_options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };

}
复制代码
然后,我们将创建一个新方法来使用类型化客户端:

复制代码
private async Task GetCompaniesWithTypedClient()
{
using (var response = await _companiesClient.Client.GetAsync(“companies”, HttpCompletionOption.ResponseHeadersRead))
{
response.EnsureSuccessStatusCode();

    var stream = await response.Content.ReadAsStreamAsync();

    var companies = await JsonSerializer.DeserializeAsync<List<CompanyDto>>(stream, _options);
}

}
复制代码
我们不是通过使用CreateClient方法来创建一个新的客户端实例。这一次,我们只使用注入类型的客户机及其client属性。最后,执行这个方法:

public async Task Execute()
{
//await GetCompaniesWithHttpClientFactory();
await GetCompaniesWithTypedClient();
}
现在让我们看看如何将相关的逻辑提取到CompaniesClient 类。

封装与类型化客户端相关的逻辑

因为我们已经有了类型化的客户端类,所以我们可以将服务中的所有相关逻辑提取到这个类中。为此,我们将修改CompaniesClient 类:

复制代码
public class CompaniesClient
{
private readonly HttpClient _client;
private readonly JsonSerializerOptions _options;

public CompaniesClient(HttpClient client)
{
    _client = client;

    _client.BaseAddress = new Uri("https://localhost:5001/api/");
    _client.Timeout = new TimeSpan(0, 0, 30);
    _client.DefaultRequestHeaders.Clear();

    _options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; 
}

}
复制代码
我们有一个私有的只读变量,将在该类中使用它来执行HttpClient的逻辑。此外,我们还添加了JsonSerializerOptions配置。现在,可以添加一个新方法:

复制代码
public async Task<List> GetCompanies()
{
using (var response = await _client.GetAsync(“companies”, HttpCompletionOption.ResponseHeadersRead))
{
response.EnsureSuccessStatusCode();

    var stream = await response.Content.ReadAsStreamAsync();

    var companies = await JsonSerializer.DeserializeAsync<List<CompanyDto>>(stream, _options);

    return companies;
}

}
复制代码
使用这个方法,我们从API中获取公司数据并返回结果。最后,可以修改服务类中的GetCompaniesWithTypedClient方法:

private async Task GetCompaniesWithTypedClient() => await _companiesClient.GetCompanies();
USB Microphone https://www.soft-voice.com/
Wooden Speakers https://www.zeshuiplatform.com/
亚马逊测评 www.yisuping.cn
深圳网站建设www.sz886.com

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值