使用HttpClientFactory,我们可以配置依赖注入来创建和管理HttpClient的生命周期:
public class GitHubService : IGitHubService
{
public HttpClient Client { get; }
public GitHubService(HttpClient client)
{
client.BaseAddress = new Uri("https://api.github.com/");
// GitHub API versioning
client.DefaultRequestHeaders.Add("Accept",
"application/vnd.github.v3+json");
// GitHub requires a user-agent
client.DefaultRequestHeaders.Add("User-Agent",
"HttpClientFactory-Sample");
Client = client;
}
public async Task<IEnumerable<GitHubIssue>> GetAspNetDocsIssues()
{
var response = await Client.GetAsync(
"/repos/aspnet/AspNetCore.Docs/issues?state=open&sort=created&direction=desc");
response.EnsureSuccessStatusCode();
using var responseStream = await response.Content.ReadAsStreamAsync();
return await JsonSerializer.DeserializeAsync
<IEnumerable<GitHubIssue>>(responseStream);
}
}
然后在Startup.cs中配置DI:
services.AddHttpClient<GitHubService>();
但是,如果类型化客户端具有其他构造函数参数,则应如何提供这些参数?例如,如果要传入仓库名称:
public class GitHubService : IGitHubService
{
public HttpClient Client { get; }
private readonly string _repositoryName;
public GitHubService(HttpClient client, string repositoryName)
{
_repositoryName = repositoryName;
client.BaseAddress = new Uri("https://api.github.com/");
// GitHub API versioning
client.DefaultRequestHeaders.Add("Accept",
"application/vnd.github.v3+json");
// GitHub requires a user-agent
client.DefaultRequestHeaders.Add("User-Agent",
"HttpClientFactory-Sample");
Client = client;
}
public async Task<IEnumerable<GitHubIssue>> GetAspNetDocsIssues()
{
var response = await Client.GetAsync(
$"/repos/aspnet/{_repositoryName}/issues?state=open&sort=created&direction=desc");
response.EnsureSuccessStatusCode();
using var responseStream = await response.Content.ReadAsStreamAsync();
return await JsonSerializer.DeserializeAsync
<IEnumerable<GitHubIssue>>(responseStream);
}
}
也许这不是一个现实的例子,但是如何配置依赖注入来提供存储库名称呢?
6条答案
按热度按时间ycggw6v21#
我设法通过切换到命名客户端来实现这一点:
pprl5pva2#
如果你不想使用命名客户端,另一种选择是为额外的参数创建一个自定义类。因为问题是它不知道为类型字符串解析什么,你可以做的是创建一个带有字符串属性的对象,该属性包含你想传递的值,将其注册为单例,让容器解析它。
创建一个包含所有额外参数的类。
注册新类
然后注册HttpClient
现在您的类将被正确示例化。
3xiyfsfu3#
也许你可以通过
HttpClient
的属性传递一个参数。仓库名称可以通过BaseAddress
传递。46scxncf4#
如果您使用Autofac作为依赖关系解析器,则可以使用它的Delegate Factories来实现此目的。
它看起来像这样
第一个
据我所知,这是不可能与内置的依赖关系解析器。
waxmsbnn5#
实际上有一个足够简单的方法可以一步完成。
gc0ot86w6#
正确的方法是使用
AddHttpClient<TClient,TImplementation>(Func<HttpClient, IServiceProvider, TImplementation>)
扩展方法: