Вы не хотите вручную взаимодействовать с контейнером вне корневого каталога композиции, поскольку не хотите или не хотите связывать свое приложение с конкретным контейнером.
В вашей ситуации вы создаете приложение, специфичное для конкретного приложения.мини-контейнер только для этого варианта использования:
public interface IDevice
{
void DoStuff();
}
public interface IDeviceProvider
{
IDevice ActiveDevice { get; set }
}
internal DeviceProvider : IServiceProvider
{
public IDevice ActiveDevice { get; set; }
}
internal class Consumer
{
public Consumer( IDeviceProvider deviceProvider )
{
_deviceProvider = deviceProvider;
}
public void UseDevice()
{
_deviceProvider.ActiveDevice?.DoStuff()??throw new Exception("No device connected");
}
private readonly IDeviceProvider _deviceProvider;
}
Вы можете улучшить это, разделив настройку активного устройства и считав активное устройство на два интерфейса и / или ограничив видимость интерфейса установки для определенных модулей,но он прекрасно работает, не имея доступа к контейнеру или даже не имея его (вы все равно не используете контейнер в своих тестах, не так ли?).
Для создания устройств вам также не нужен контейнер,в качестве единицы можно ввести, например, Func<DeviceA>
для создания DeviceA
экземпляров, когда это необходимо.