.NET Core 3 Worker 服务设置依赖注入
.NET Core 3 Worker Service Settings Dependency Injection
我在 .NET Core 2 中成功运行了以下内容,但在 .NET Core 3 中不起作用。
我从头开始创建了一个新的 Worker Service .Net Core 3 项目,并且只添加了最少的项目来重现我的错误。
这是我在 Program.cs
中的切入点
namespace WorkerService1DeleteMe
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
services.Configure<ConfigChunk>(hostContext.Configuration.GetSection("ConfigChunk"));
services.AddHostedService<Worker>();
});
}
public class ConfigChunk
{
public string Server { get; set; }
}
}
所以在 CreateHostBuilder
中添加了一行到 Configure
方法,并在底部添加了一个新的 ConfigChunk
class 来匹配模式appsettings.json.
中的一个部分
最后,将参数扩展到 Worker 构造函数以使其使用 SettingsChunk:
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
private readonly ConfigChunk _config;
public Worker(ILogger<Worker> logger, ConfigChunk config)
{
_logger = logger;
_config = config;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
await Task.Delay(1000, stoppingToken);
}
}
}
如前所述,这在 NET Core 2 中运行良好,但在 3 中失败:
Unable to resolve service for type 'WorkerService1DeleteMe.ConfigChunk' while attempting to activate 'WorkerService1DeleteMe.Worker'.
我觉得我错过了一些非常明显的东西,但我必须承认我不知所措。我观察到的是,我可以通过 services.AddSingleton
而不是 services.Configure
来使整个工作正常进行,但是如果我可以使它工作,我更喜欢 Configure 方法的模式和重新加载功能。
可用的选项很少。
与当前配置更新工作者一起使用IOptions<TOptions>
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
private readonly ConfigChunk _config;
public Worker(ILogger<Worker> logger, IOptions<ConfigChunk> config) {
_logger = logger;
_config = config.Value;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken) {
while (!stoppingToken.IsCancellationRequested) {
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
await Task.Delay(1000, stoppingToken);
}
}
}
或者让 worker 保持原样并更新配置以允许 class 本身被注入。
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) => {
services.Configure<ConfigChunk>(hostContext.Configuration.GetSection("ConfigChunk"));
services.AddHostedService<Worker>();
services.AddTransient<ConfigChunk>(_ => _.GetRequiredService<IOptions<ConfigChunk>>().Value);
});
第二个示例将允许 ConfigChunk
的显式注入,同时仍然允许选项功能生效,并且不会将 worker 与框架问题紧密耦合。
我在 .NET Core 2 中成功运行了以下内容,但在 .NET Core 3 中不起作用。
我从头开始创建了一个新的 Worker Service .Net Core 3 项目,并且只添加了最少的项目来重现我的错误。
这是我在 Program.cs
中的切入点namespace WorkerService1DeleteMe
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
services.Configure<ConfigChunk>(hostContext.Configuration.GetSection("ConfigChunk"));
services.AddHostedService<Worker>();
});
}
public class ConfigChunk
{
public string Server { get; set; }
}
}
所以在 CreateHostBuilder
中添加了一行到 Configure
方法,并在底部添加了一个新的 ConfigChunk
class 来匹配模式appsettings.json.
最后,将参数扩展到 Worker 构造函数以使其使用 SettingsChunk:
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
private readonly ConfigChunk _config;
public Worker(ILogger<Worker> logger, ConfigChunk config)
{
_logger = logger;
_config = config;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
await Task.Delay(1000, stoppingToken);
}
}
}
如前所述,这在 NET Core 2 中运行良好,但在 3 中失败:
Unable to resolve service for type 'WorkerService1DeleteMe.ConfigChunk' while attempting to activate 'WorkerService1DeleteMe.Worker'.
我觉得我错过了一些非常明显的东西,但我必须承认我不知所措。我观察到的是,我可以通过 services.AddSingleton
而不是 services.Configure
来使整个工作正常进行,但是如果我可以使它工作,我更喜欢 Configure 方法的模式和重新加载功能。
可用的选项很少。
与当前配置更新工作者一起使用IOptions<TOptions>
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
private readonly ConfigChunk _config;
public Worker(ILogger<Worker> logger, IOptions<ConfigChunk> config) {
_logger = logger;
_config = config.Value;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken) {
while (!stoppingToken.IsCancellationRequested) {
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
await Task.Delay(1000, stoppingToken);
}
}
}
或者让 worker 保持原样并更新配置以允许 class 本身被注入。
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) => {
services.Configure<ConfigChunk>(hostContext.Configuration.GetSection("ConfigChunk"));
services.AddHostedService<Worker>();
services.AddTransient<ConfigChunk>(_ => _.GetRequiredService<IOptions<ConfigChunk>>().Value);
});
第二个示例将允许 ConfigChunk
的显式注入,同时仍然允许选项功能生效,并且不会将 worker 与框架问题紧密耦合。