phi*_*eed 8 c# asp.net asp.net-web-api asp.net-core
使用HttpClientFactory我们可以配置依赖注入来创建和管理 HttpClients 的生命周期:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
然后在 Startup.cs 中我们配置 DI:
services.AddHttpClient<GitHubService>();
Run Code Online (Sandbox Code Playgroud)
但是,如果类型化的客户端有额外的构造函数参数,应该如何提供这些参数?例如,如果要传入存储库名称:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
也许这不是一个现实的例子,但是如何配置依赖注入来提供存储库名称?
phi*_*eed 10
我设法通过切换到命名客户端来完成这项工作:
//To start with, create a named client:
services.AddHttpClient("GitHubClient", ctx => { ctx.BaseAddress = new Uri("https://api.github.com/"); });
//Then set up DI for the TypedClient
services.AddTransient<IGitHubService>(ctx =>
{
var clientFactory = ctx.GetRequiredService<IHttpClientFactory>();
var httpClient = clientFactory.CreateClient("GitHubClient");
return new GitHubService(httpClient, repositoryName);
});
Run Code Online (Sandbox Code Playgroud)
实际上有一种足够简单的方法可以一步完成此操作。
services.AddHttpClient<IGitHubService, GitHubService>((client, sp) =>
{
client.BaseAddress = new Uri("https://api.github.com/");
return new GitHubService(client, repositoryName);
});
Run Code Online (Sandbox Code Playgroud)
如果您不想使用命名客户端,另一种方法是为额外参数创建自定义类。因为问题在于它不知道要为类型字符串解析什么,所以您可以做的是创建一个带有字符串属性的对象,该对象将包含您要传递的值,将其注册为单例并让容器解决它。
创建一个包含所有额外参数的类。在你的情况下“repositoryName”
public class RepositoryConfig
{
public string RepositoryName {get; set;}
}
Run Code Online (Sandbox Code Playgroud)
注册新班级
services.AddSingleton(new RepositoryConfig { RepositoryName = "MyRepo"});
Run Code Online (Sandbox Code Playgroud)
然后注册HttpClient
services.AddHttpClient<IGitHubService, GitHubService>();
Run Code Online (Sandbox Code Playgroud)
现在您的类将被正确实例化。
| 归档时间: |
|
| 查看次数: |
4935 次 |
| 最近记录: |