c# - 控制台应用程序后台服务中 httpclientfactory 的 DI
问题描述
我有一个带有简单消费后台服务的控制台程序,该程序需要从使用 HttpClientFactory 的作用域服务调用函数来调用外部 API 并将结果返回给使用后台服务。
在在线查看几个示例以消除代码中所有可能的复杂性之后,我想要非常简单。
public class Program
{
public static async Task Main(string[] args)
{
var host = new HostBuilder()
.ConfigureLogging((hostContext, config) =>
{
config.AddConsole();
})
.ConfigureAppConfiguration((hostContext, config) =>
{
config.AddJsonFile("appsettings.json", optional: true);
config.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true);
config.AddCommandLine(args);
})
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<ConsumeMessageService>();
services.AddScoped<IScopedArcGisServices, ScopedArcGisServices>();
})
.UseConsoleLifetime()
.Build();
using (host)
{
// Start the host
await host.StartAsync();
// Wait for the host to shutdown
await host.WaitForShutdownAsync();
}
}
}
public class ConsumeMessageService : IHostedService
{
private readonly ILogger _logger;
public IServiceProvider _serviceProvider { get; }
public ConsumeMessageService(IServiceProvider services,
ILogger<ConsumeMessageService> logger)
{
_serviceProvider = services;
_logger = logger;
}
public Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogInformation(
"Consume message service hosted service is starting.");
DoWork();
return Task.CompletedTask;
}
private void DoWork()
{
_logger.LogInformation(
"Consume message service hosted service is working.");
using (var scope = _serviceProvider.CreateScope())
{
var scopedProcessingService =
scope.ServiceProvider
.GetRequiredService<IScopedServices>();
scopedProcessingService.DoWork();
}
}
public Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogInformation(
"Consume Scoped Service Hosted Service is stopping.");
return Task.CompletedTask;
}
}
internal interface IScopedServices
{
void DoWork();
}
internal class ScopedServices : IScopedServices
{
private readonly ILogger _logger;
private readonly IHttpClientFactory _clientFactory;
public string JsonResult { get; private set; }
public ScopedServices(ILogger<ScopedServices> logger, IHttpClientFactory clientFactory)
{
_logger = logger;
_clientFactory = clientFactory;
}
public void DoWork()
{
_logger.LogInformation("Scoped processing service is working.");
}
}
一旦我使用 HttpClientFactory 获得 scopedservice,我就会收到以下消息:
尝试激活“Integration.BackgroundService.Services.ScopedServices”时无法解析“System.Net.Http.IHttpClientFactory”类型的服务。
解决方案
IHttpClientFactory
默认不添加。
您必须services.AddHttpClient()
在配置服务时调用以添加对工厂及其相关客户端的访问权限。
//...
.ConfigureServices((hostContext, services) => {
services.AddHttpClient(); //<-- THIS IS NEEDED
services.AddHostedService<ConsumeMessageService>();
services.AddScoped<IScopedArcGisServices, ScopedArcGisServices>();
})
//...
有关如何配置工厂创建的客户端的更多信息,
参考使用 HttpClientFactory 实现弹性 HTTP 请求
推荐阅读
- python - 无法使用 popen 重定向 IO
- python - 带有验证的会话帖子在 python3.7.2 中不起作用
- c# - 如何使用 Entity Framework Core 和 Npgsql 清理我的所有字符串输入?
- python - 如何使用 Pandas 执行 first() 和 max() groupby 的等效(来自 SQL)?
- r - dplyr 函数 group_by 几个变量
- python - RASA X 路径“config.yml”不存在。请确保使用默认位置 ('config.yml') 或使用 '--config' 指定它
- kubernetes - 使用 prometheus-nginx-exporter 监控多个 nginx-proxy pod
- java - Java 泛型不适用于参数列表