Как настроить параметры приложения в рабочей службе .Net Core 3

Я просмотрел ряд руководств и вопросов SO (таких как App Settings.Net Core) относительно чтения appsettings.json в.Net Core 3, и я не могу найти никаких указателей на то, как работать со службой Worker. Нет способа запуска. Вместо этого у меня есть Program.cs с основным методом:

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

Как мне приступить к чтению из файла appsettings.json в проекте Worker Service Project в.Net Core 3?

Я добавил ссылку на настраиваемый клиент WCF, который я создал с помощью.Net v4.8, и еще один проект, в котором есть только все объекты бизнес-домена, общие для всего решения. Мое решение - в первую очередь.Net v4.8, и я хочу использовать Worker Service. Проект Client создает клиент WCF внутри с помощью кода, поэтому все привязки и конечные точки можно настраивать. Если бы это был проект.Net v4.8, я бы добавил в 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>

Теперь мне нужно, чтобы эти настройки были в новом формате JSON и прочитали их.

редактировать

Это свежий проект. Рабочий ничего не делает:

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

И вот как я получаю этот тип проекта:

3 ответа

Решение

Если, например, рабочему классу нужен доступ к некоторым данным, хранящимся в ваших настройках приложения

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

где WorkerOptions хранит ваши значения из конфигурации.

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

    //... other properties
}

Предполагается, что файл appsettings.json имеет соответствующие ключи

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

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

}

По умолчанию Host.CreateDefaultBuilder настроит обычную конфигурацию (appsettings.json и др.).

Использовать hostContext.Configuration чтобы получить IConfigurationЭкземпляр, который можно использовать для доступа к желаемым настройкам и добавления для него строго типизированной объектной модели. Добавьте этот объект в коллекцию сервисов, чтобы его можно было внедрить там, где это необходимо.

Например

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

Когда воркер создается, ему будут внедрены необходимые ему зависимости.

Эталонная конфигурация в ASP.NET Core

Как я это сделал:

Программа.cs:

      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;
                services.Configure<RabbitMQConfiguration>(configuration.GetSection(nameof(RabbitMQConfiguration)));
                services.AddHostedService<Worker>();
            });
}

В вашем работнике вы можете получить доступ к таким параметрам:

      public Worker(ILogger<Worker> logger, IOptions<RabbitMQConfiguration> options)
{
    _queue = options.Value.RabbitMQUrl;
    _options = options.Value;
    _logger = logger;
}

Вам также понадобится класс для вашего объекта параметров:

      public class RabbitMQConfiguration
{
    public string RabbitMQUrl { get; set; }
    public string Username { get; set; }
    public string Password { get; set; }
   // ...
}

В appsettings.json

      {
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "RabbitMQConfiguration": {
    "RabbitMQUrl": "rabbitmq://yoururl",
    "Username": "admin",
    "Password": "mypassword",
  }
}

В продолжение ответа Никоси Вы также можете установить параметры в классе Startup в методе ConfigureService, примерно так:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }
    
    public void ConfigureServices(IServiceCollection services)
    {
        // others services configuration
        WorkerOptions options = 
            Configuration.GetSection("WCF").Get<WorkerOptions>();

        services.AddSingleton(options);
        services.AddHostedService<Worker>();
    }
}
Другие вопросы по тегам