本文介绍了.NET Core 3 Worker服务设置依赖项注入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下在.NET Core 2中成功运行的东西,但在.NET Core 3中不起作用。



我做了一个新的工作者服务.Net Core 3项目从零开始,仅添加了最小的重新创建错误。



这是我在 Program.cs 中的入口点p>

 命名空间WorkerService1DeleteMe 
{
公共类程序
{
public static void Main( string [] args)
{
CreateHostBuilder(args).Build()。Run();
}

公共静态IHostBuilder CreateHostBuilder(string [] args)=>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext,services)=>
{
services.Configure< ConfigChunk>(hostContext.Configuration.GetSection( ConfigChunk ));
services.AddHostedService< Worker>();
});
}

公共类ConfigChunk
{
公共字符串Server {get;组; }
}
}

因此 CreateHostBuilder Configure 方法,以及一个新的 ConfigChunk 类在底部,以匹配 appsettings.json 中某节的模式。



最后,将参数扩展到Worker构造函数以让它消耗SettingsChunk:

 公共类Worker:BackgroundService 
{
private readonly ILogger< Worker> _logger;
私有只读ConfigChunk _config;

公共工作者(ILogger< Worker>记录器,ConfigChunk配置)
{
_logger = logger;
_config =配置;
}

受保护的覆盖异步任务ExecuteAsync(CancellationToken stopToken)
{
while(!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation (工作人员在{time}处运行,DateTimeOffset.Now);
等待Task.Delay(1000,StoppingToken);
}
}
}

如所暗示的,这可行在NET Core 2中可以正常使用,但在3中失败:

我觉得我遗漏了一些显而易见的东西,但必须承认我茫然。我观察到的是,我可以通过使用 services.AddSingleton 而不是 services.Configure 来使整个工作正常进行,但是如果可以,我更喜欢Configure方法的模式和重新加载功能。

解决方案

几乎没有可用的选项。 / p>

在当前配置下,更新工作程序可以使用 IOptions< TOptions>

 公共类Worker:BackgroundService 
{
private只读ILogger< Worker> _logger;
私有只读ConfigChunk _config;

公共工作者(ILogger< Worker>记录器,IOptions< ConfigChunk>配置){
_logger =记录器;
_config = config.Value;
}

受保护的覆盖异步任务ExecuteAsync(CancellationToken stopToken){
while(!stoppingToken.IsCancellationRequested){
_logger.LogInformation(工作人员在以下时间运行: },DateTimeOffset.Now);
等待Task.Delay(1000,StoppingToken);
}
}
}

或者直接离开工人

  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 ,同时仍允许选项功能生效,并且不会将工作人员与框架问题紧密联系在一起。


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:

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.

解决方案

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.

这篇关于.NET Core 3 Worker服务设置依赖项注入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-29 00:47
查看更多