添加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