Como definir configurações de aplicativos em um serviço .Net Core 3 Worker

22

Eu estive analisando vários tutoriais e perguntas de SO (como App Settings .Net Core ) sobre a leitura de appsettings.json no .Net Core 3 e não consigo encontrar dicas sobre como fazer ao lidar com o serviço Worker. Não há método de inicialização. Em vez disso, eu tenho um Program.cs com o método principal:

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.AddHostedService<Worker>();
            });
}

Como faço para ler o arquivo appsettings.json em um Projeto de Serviço do Trabalhador no .Net Core 3?

Adicionei uma referência a um cliente WCF personalizado que criei com o .Net v4.8 e outro projeto que possui apenas todo o Objeto de Domínio Busines compartilhado entre toda a solução. Minha solução é principalmente .Net v4.8 e quero usar o Serviço do Trabalhador. O projeto Client cria um cliente WCF internamente por código, para que todas as ligações e pontos de extremidade sejam configuráveis. Se esse fosse um projeto .Net v4.8, adicionaria o seguinte ao app.config:

<appSettings>
    ...
    <add key="AminServiceUri" value="http://localhost:45108/ServiceHost/v1/AminService.svc" />
    <add key="BillServiceUri" value="http://localhost:45108/ServiceHost/v1/BillService.svc" />
    <add key="CustomerServiceUri" value="http://localhost:45108/ServiceHost/v1/CustomerService.svc" />
    <add key="EpayServiceUri" value="http://localhost:45108/ServiceHost/v1/EpayService.svc" />
    <add key="FinanceServiceUri" value="http://localhost:45108/ServiceHost/v1/FinanceService.svc" />
    <add key="GrpServiceUri" value="http://localhost:45108/ServiceHost/v1/GrpService.svc" />
    <add key="MetaServiceUri" value="http://localhost:45108/ServiceHost/v1/MetaService.svc" />
    <add key="ReportServiceUri" value="http://localhost:45108/ServiceHost/v1/ReportService.svc" />
    <add key="ServiceInfoServiceUri" value="http://localhost:45108/ServiceHost/v1/ServiceInfoService.svc" />
    <add key="UsersServiceUri" value="http://localhost:45108/ServiceHost/v1/UsersService.svc" />
    ...
    <add key="ExcessiveLogging" value="false" />
    ...
</appSettings>

Agora, preciso que essas configurações estejam no novo formato JSON e as leia.

Editar

Este é um projeto novo. O trabalhador não está fazendo nada:

public class Worker : BackgroundService
{
    private readonly ILogger<Worker> logger;

    public Worker(ILogger<Worker> logger)
    {
        this.logger = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
            await Task.Delay(5000, stoppingToken);
        }
    }
}

E aqui está como eu recebo esse tipo de projeto:

Serviço ao Trabalhador

Hassan Gulzar
fonte

Respostas:

36

Se, por exemplo, a classe de trabalhador precisar acessar alguns dados armazenados em suas configurações de aplicativos

public class Worker : BackgroundService {
    private readonly ILogger<Worker> logger;
    private readonly WorkerOptions options;

    public Worker(ILogger<Worker> logger, WorkerOptions options) {
        this.logger = logger;
        this.options = options;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken) {
        while (!stoppingToken.IsCancellationRequested) {
            //do something that uses options

            logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
            await Task.Delay(5000, stoppingToken);
        }
    }
}

Onde WorkerOptionsarmazena seus valores da configuração.

public class WorkerOptions {
    public string AminServiceUri { get; set; }
    public string BillServiceUri { get; set; }

    //... other properties
}

Que assume que o arquivo appsettings.json possui as chaves correspondentes

{
  "WCF": {
    "AminServiceUri":"http://localhost:45108/ServiceHost/v1/AminService.svc",
    "BillServiceUri":"http://localhost:45108/ServiceHost/v1/BillService.svc",

    //...other key-value pairs
  },
  "Logging": {
    "ExcessiveLogging": false
  }

}

Por padrão Host.CreateDefaultBuilder irá definir a configuração usual (appsettings.json et al).

Usar hostContext.Configuration para obter a IConfigurationinstância que pode ser usada para acessar as configurações desejadas e adicionar o modelo de objeto fortemente tipado a ela. Adicione esse objeto à coleção de serviços para que possa ser injetado onde necessário

Por exemplo

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) => {
                IConfiguration configuration = hostContext.Configuration;

                WorkerOptions options = configuration.GetSection("WCF").Get<WorkerOptions>();

                services.AddSingleton(options);

                services.AddHostedService<Worker>();
            });
}

Quando o trabalhador estiver sendo criado, ele será injetado com as dependências necessárias.

Configuração de referência no núcleo do ASP.NET

Nkosi
fonte
Esta resposta é tão perfeita. Ele fornece a maneira correta de ler dados das configurações do aplicativo.
precisa
Você pode usar em IConfigurationvez de criar uma classe personalizada
Shimon Lebovits