有没有更好的方法使用 DI 容器来处理 link 相关依赖项?

Is there a better way to link related dependencies using a DI Container?

我需要获取所有连接的串行端口并从中获取轮询信息。所以我写了一个 Helper 来获取连接的 SerialPorts,在 Startup.ConfigureService 方法中循环它们并将它们添加到 DI 容器中:

foreach (var serialPort in SystemInformationHelper.GetSerialPorts())
{
   services.AddSingleton<IAddress>(sp => new SerialAddress(serialPort));
   services.AddSingleton<IConnection, SerialConnection>();
   services.AddSingleton<IDevice, PollingDevice>();
}

然后我使用构造函数注入来获取我的 PollingDevice 中的所有连接和我的连接中的所有地址 Class。参见 Class 图:

现在我为启动轮询过程所需的启动方法提供了一个索引以获取正确的注入连接,并向用于控制连接设备的项目添加了一个 HostedService。

public class ControllerInitializer : IHostedService
{
   private readonly IEnumerable<IDevice> _devices;

   public ControllerInitializer(IEnumerable<IDevice> devices)
   {
      _devices = devices;
   }

   public Task StartAsync(CancellationToken cancellationToken)
   {
      for(int i = 0; i < _devices.Count(); i++)
      {
        _devices.ElementAt(i).Startup(i);
      }
      return Task.CompletedTask;
   }

   public Task StopAsync(CancellationToken cancellationToken)
   {
       for (int i = 0; i < _devices.Count(); i++)
       {
          _devices.ElementAt(i).Shutdown();
       }
       return Task.CompletedTask;
   }
}

它有效,但我刚开始使用 DI,想知道是否有更好的解决方案我不知道。

注入 IEnumerable<T> 依赖项对于 DI 来说是很常见的事情,所以这对我来说似乎非常合理。

例如,Microsoft 使用相同的模式来注入检索所有 IHostedService 以调用 StartAsync/StopAsync。唯一的区别是它们直接从 IServiceProvider 中检索依赖项,而不是将其注入构造函数。

我唯一要改变的是使用 foreach 循环而不是 for 循环和 IEnumerable:

public Task StartAsync(CancellationToken cancellationToken)
{ 
    var connectionIndex = 0;
    foreach (var device in _devices) 
    {
        device.Startup(connectionIndex);
        connectionIndex++;
    }

    return Task.CompletedTask;
}