Используя 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.
Мой вопрос состоит из двух частей: как вы, ребята, справляетесь с созданием объектов для зависимостей, которые сами содержат зависимости, в простым способом?
И ... как вы разделяете конфигурацию контейнера для создания объектов в целях тестирования?
Как всегда, приветствуются любые комментарии или ссылки на соответствующие сообщения.