Контейнер DI для объекта, который содержит объект с внедренной зависимостью

Используя pimple в качестве контейнера DI, я смело реорганизовал небольшие классы, чтобы полагаться на внедрение DI, устранив жестко запрограммированные зависимости, которые, как я мог видеть, можно было бы легко удалить.

Моя методология решения этой задачи очень проста, но я понятия не имею, правильна ли она, поскольку у меня очень мало опыта с DI и модульным тестированием, помимо того, что я узнал здесь в прошлом месяце.

Я создал класс ContainerFactory, который является подклассом pimple, и в этом подклассе создал методы, которые просто возвращают контейнер для определенного объекта.

Конструктор вызывает соответствующий метод создателя в зависимости от типа:

function __construct($type=null, $mode = null){

 if(isset($type)){  
    switch ($type) {
      case 'DataFactory':
         $this->buildDataFactoryContainer($mode);     
        break;
      case 'DbConnect':
         $this->buildDbConnectContainer($mode);  
        break;
     default:
        return false;
    }
  }
}

Сигнатура метода для создания объекта-контейнера выглядит следующим образом:

public function buildDataFactoryContainer($mode=null)

Идея состоит в том, что я могу установить $ mode для тестирования при вызове этого контейнера и получить его значения нагрузочного теста вместо фактических настроек времени выполнения. Я хотел избежать написания отдельных контейнерных классов для тестирования, и я думал, что это простой способ избавиться от кода, связанного с тестированием.

Вместо этого я мог бы создать подкласс ContainerFactory, например: ContainerFactoryTesting расширяет ContainerFactory и переопределяет это вместо того, чтобы смешивать тестовый код с кодом приложения и загромождать сигнатуры методов с помощью $ mode = null, но суть не в этом сообщение. Двигаясь дальше, чтобы создать контейнер для определенного объекта, я просто делаю следующее:

 // returns container with DataFactory dependencies, holds $db and $logger objects.
 $dataFactoryContainer = new ContainerFactory('DataFactory');

// returns container with test settings.
$dataFactoryTestContainer = new ContainerFactory('DataFactory','test');

// returns container with DbConnect dependencies, holds dbconfig and $logger objects.
$dbConnectContainer = new ContainerFactory('DbConnect');

Я только что столкнулся с проблемой, которая заставляет меня подозревать, что стратегия, на которой я строю, ошибочна.

Глядя на вышесказанное, DataFactory содержит Объект $ db, содержащий подключения к базе данных. Сейчас я реорганизую этот dbclass, чтобы удалить его зависимости от объекта $ registry, но как мне создать $ dataFactoryContainer, когда я добавлю объект $ db, которому требуется $ dbConnectContainer?

Например, в контейнере datafactory я добавляю экземпляр dbconnect, но теперь ИТ-специалисту потребуется переданный ему контейнер ...

Я понимаю, что мой английский не так хорош, и надеюсь, что я объяснил достаточно хорошо, чтобы его мог понять другой SO'er.

Мой вопрос состоит из двух частей: как вы, ребята, справляетесь с созданием объектов для зависимостей, которые сами содержат зависимости, в простым способом?

И ... как вы разделяете конфигурацию контейнера для создания объектов в целях тестирования?

Как всегда, приветствуются любые комментарии или ссылки на соответствующие сообщения.

5
задан Rodia 22 April 2018 в 20:33
поделиться