У меня есть среда с 4 одинаковыми устройствами, к которым я должен подключиться и запросить некоторые параметры через соединение TCP (каждое устройство со своим IP-адресом). Я реализовал класс для одного устройства, которому нужны некоторые параметры (например, IP-адрес, порт, интервалы опроса и т. Д.)
Класс реализует интерфейс BackgroundService
и имеет конструктор, подобный приведенному ниже:
public RemoteDevice(RemoteDeviceConfig config, ILogger<RemoteDevice> logger)
Внутри класса есть реализация метода ExecuteAsync
с циклом while{}
, который выполняет всю логику.
Я хочу создать рабочую службу, котораяобрабатывает несколько экземпляров этого класса на основе файла конфигурации (например, файла конфигурации с массивом устройств)
В Program.cs я бы сделал:
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSystemd()
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<RemoteDevice>(); //First device
services.AddHostedService<RemoteDevice>(); //Second device
...
services.AddHostedService<RemoteDevice>(); //n-th device
});
...
//Methods to load configuration
...
Без RemoteDeviceConfig
параметр конструктора, ILogger
вводится, но если я его добавлю, я не знаю, как внедрить мой RemoteDeviceConfig
класс
Что я делаю не так?
I 'Я использую .NET Core 3.0 с VS2019 и проектом Worker Service Template.
ОБНОВЛЕНИЕ - ПРИНЯТ ОТВЕТ
Я принял @ gldraphael ответ , и я хотел бы добавить некоторые подробности о спецификации части регистрациив комментариях ответа.
Проблема: использовать реализацию ILogger в классах, созданных в основном классе Worker.
Решение: внедрить ILoggerFactory в класс Worker и использовать его для создания регистраторов для подклассов
DeviceMainClass
и DeviceConfig
- соответственно общий диспетчер устройств и его конфигурация.
Worker.cs
List<DeviceMainClass> devices;
//Pass ILoggerFactory to worker constructor for Dependency Injection
//On worker start, instantiate all subclasses and create logger for each class
public Worker(IOptions<List<DeviceConfig>> options, ILogger<Worker> logger, ILoggerFactory loggerFactory)
{
devices = new List<DeviceMainClass>();
foreach(var device in _config)
{
devices.Add(new DeviceMainClass(_loggerFactory.CreateLogger<DeviceMainClass>(),...other parameters));
}
_logger = logger;
_loggerFactory = loggerFactory;
_config = options.Value;
}
...
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
//***for testing purposes only, repeats every second***
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
await Task.Delay(1000, stoppingToken);
}
}
DeviceMainClass
private readonly ILogger<DeviceMainClass> _logger;
//Use
public DeviceMainClass(ILogger<DeviceMainClass> logger, ...other parameters)
{
_logger = logger;
...
}