Cómo configurar los ajustes de la aplicación en un .Net Core 3 Worker Service

22

He estado mirando una serie de tutoriales y preguntas SO (como la Configuración de la aplicación .Net Core ) con respecto a la lectura de appsettings.json en .Net Core 3 y no puedo encontrar ningún indicador sobre cómo hacerlo cuando trato con el servicio Worker. No hay método de inicio. En cambio, tengo un Program.cs con el 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>();
            });
}

¿Cómo hago para leer el archivo appsettings.json en un proyecto de servicio para trabajadores en .Net Core 3?

He agregado una referencia a un cliente WCF personalizado que creé con .Net v4.8 y otro proyecto que tiene todos los objetos de dominio de Busines compartidos entre toda la solución. Mi solución es principalmente .Net v4.8 y quiero usar el Servicio de trabajo. El proyecto del Cliente crea un Cliente WCF internamente por código para que todos los enlaces y puntos finales sean configurables. Si este fuera un proyecto .Net v4.8, agregaría lo siguiente a 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>

Ahora necesito esta configuración para estar en el nuevo formato JSON y leerla.

Editar

Este es un proyecto nuevo. El trabajador no está haciendo 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);
        }
    }
}

Y así es como obtengo este tipo de proyecto:

Servicio de trabajo

Hassan Gulzar
fuente

Respuestas:

36

Si, por ejemplo, la clase trabajadora necesita acceso a algunos datos almacenados en sus ajustes de aplicaciones

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

Donde WorkerOptionsalmacena sus valores de la configuración.

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

    //... other properties
}

Lo que supone que el archivo appsettings.json tiene las claves correspondientes

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

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

}

De forma predeterminada Host.CreateDefaultBuilder, configurará la configuración habitual (appsettings.json et al).

Se usa hostContext.Configurationpara obtener la IConfigurationinstancia que se puede usar para acceder a la configuración deseada y agregarle el modelo de objeto fuertemente tipado. Agregue ese objeto a la colección de servicios para que pueda inyectarse donde sea necesario

Por ejemplo

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

Cuando se crea el trabajador, se le inyectarán las dependencias necesarias.

Configuración de referencia en ASP.NET Core

Nkosi
fuente
Esta respuesta es tan perfecta. Proporciona la forma correcta de leer datos de la configuración de la aplicación.
Vighnesh
Puede usar en IConfigurationlugar de crear una clase personalizada
Shimon Lebovits