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