.NET Core 3 Worker Service Settings Dependency Injection

我的梦境 提交于 2019-12-02 12:31:24

问题


I have the following successfully working in .NET Core 2, but it doesn't work in .NET Core 3.

I've made a new Worker Service .Net Core 3 project from scratch and added only the minimum to recreate my error.

Here is my entry point in 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; }
    }
}

So there is a single line added to CreateHostBuilder here, to the Configure method, and a new ConfigChunk class at the bottom, to match the schema of a section in appsettings.json.

Finally, an extension of the parameters to the Worker constructor to let it consume the 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);
        }
    }
}

As alluded to, this works fine in NET Core 2, but in 3 it fails with:

Unable to resolve service for type 'WorkerService1DeleteMe.ConfigChunk' while attempting to activate 'WorkerService1DeleteMe.Worker'.

I feel like I am missing something blindingly obvious but must confess I am at a loss. What I have observed is that I can make the whole thing work by going services.AddSingleton instead of services.Configure but I much prefer the pattern and reload functionality of the Configure approach if I can make it work.


回答1:


Few options are available.

With current configuration update worker to use 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);
        }
    }
}

Or leave the worker as is and update the configuration to allow the class itself to be injected.

    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);

            });

The second example will allow for explicit injection of the ConfigChunk while still allowing the options features to be in effect and does not tightly couple the worker to framework concerns.



来源:https://stackoverflow.com/questions/58288674/net-core-3-worker-service-settings-dependency-injection

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!