Каковы причины для PHP Frameworks использовать Dependency Injection Container для создания объектов?

Я собираюсь сосредоточиться на Zend Framework, потому что я знаю его лучше, но это, безусловно, применимо к другим аналогичным механизмам, встречающимся в других PHP-фреймворках, которые используют контейнер Inverstion of Control.

В случае Zend Framework с небольшим рефакторингом / манипуляциями вполне возможно не использовать контейнер.

Рабочий пример

Глядя на документы, в настоящее время Zend Framework делает что-то подобное с $container (взято отсюда):

function getServiceConfig()
{
    return [
        'factories' => [
            Model\AlbumTable::class => function ($container)
            {
                $tableGateway = $container->get(Model\AlbumTableGateway::class);
                return new Model\AlbumTable($tableGateway);
            },
            Model\AlbumTableGateway::class => function ($container)
            {
                $dbAdapter = $container->get(AdapterInterface::class);
                $resultSetPrototype = new ResultSet();
                $resultSetPrototype->setArrayObjectPrototype(new Model\Album());
                return new TableGateway('album', $dbAdapter, null, $resultSetPrototype);
            }
        ]
    ];
}

//to call
$albumTable = $container->get(Model\AlbumTable::class)

Левая сторона => содержит "ключи", которые могут быть любой строкой, включая строку определения класса. Справа находится обратный вызов или полное доменное имя для имени класса. В приведенном выше примере это анонимная функция PHP, которая действует как фабрика для создания новой сущности, используя DiC $container который передается этой функции через вызов Framework.

Почему бы не удалить контейнер и сделать что-то вроде этого:

//define
function AlbumTableFactory()
{
    $tableGateway = AlbumTableGatewayFactory();
    return new Model\AlbumTable($tableGateway);
}

function AlbumTableGatewayFactory()
{
    $dbAdapter = AdapterInterface();
    $resultSetPrototype = new ResultSet();
    $resultSetPrototype->setArrayObjectPrototype(new Model\Album());
    return new TableGateway('album', $dbAdapter, null, $resultSetPrototype);
}

//to call
$albumTable = AlbumTableFactory();

Выше можно преобразовать в классы, если голые функции надоедают.

В вышеупомянутом я удалил $container и заменил любое использование контейнера жестко закодированным new вызовы функций и так как не было предоставленных параметров

Так как factories массив является частью конфигурации контейнера Zend, чтобы по-настоящему его выделить, мне придется заменить любые другие экземпляры контейнера, вызывающего Model\AlbumTable::class с фабричным вызовом, чтобы вернуть Model\AlbumTable пример. Как только это будет сделано, у меня может появиться реализация без Zend-контейнера, где я буду вызывать фабрики напрямую, а не вызывать их через контейнер со всеми явно определенными зависимостями.

Суть вопроса в том, зачем использовать контейнер, что именно он обеспечивает, и почему бы просто не использовать "реальный код PHP" с тем преимуществом, что через контейнер не будут скрываться зависимости.

0 ответов

Другие вопросы по тегам