.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 与框架问题紧密耦合。