PhalconPHP DI: инициализаторы

В настоящее время я тестирую phalcon php для проекта и ищу способ автоматического внедрения определенных классов автоматически на основе реализованного интерфейса.

Ссылка на внедрение зависимостей есть пример, где, если класс реализует Phalcon\DI\InjectionAwareInterface, он автоматически вставит DI в этот класс.

То, что я хочу сделать, похоже. Если класс имеет, например, Aranea\Db\DbAdapterAware, он должен автоматически внедрить DbAdapter в этот класс. Я ищу что-то похожее на то, что делает Zend Framework 2 (https://juriansluiman.nl/article/121/interface-injection-with-initializers-in-zend-servicemanager), где во время настройки DI вы можете указать инициализаторы следующим образом:

'initializers' => array(
'logger' => function($service, $sm) {
if ($service instanceof LoggerAwareInterface) {
$logger = $sm->get('logger');
$service->setLogger($logger);
}
}
),

Если это не возможно автоматически в PhalconPHP, я думал об отмене FactoryDefault Класс и реализовать его сам. Каково было бы правильное место, чтобы ввести эту логику? В методах get *, точнее в set * методов? Я предполагаю, что метод инициализируется не во время инициализации DI, а при первом вызове, так что get * будет более подходящим?

Спасибо за совет,

Йерун

1

Решение

Ссылка на внедрение зависимостей содержит пример, где, если класс реализует Phalcon\DI\InjectionAwareInterface, он автоматически вставит DI в этот класс.

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

Если класс имеет, например, Aranea\Db\DbAdapterAware, он должен автоматически внедрить DbAdapter в этот класс.

Вот как это работает (не технически), если ваш класс расширяет Phalcon\DI\Injectable (или реализует InjectionAwareInterface так же, как Phalcon\DI\Injectable). внутри Injectable Eсть __get magic, которая возвращает сервис из DI, если сервис существует. Другими словами, вещи вводятся только в DI, а другие классы ищут там службы.

Чтобы внедрить ваши собственные сервисы, вы можете либо передать их в вашей конфигурации DI, либо расширить DI или же FactoryDefault, Разница между ними заключается в том, что FactoryDefault уже поставляется с предварительно настроенными полезными службами, которые вам могут не понадобиться.

Я предполагаю, что метод инициализируется не во время инициализации DI, а при первом вызове, так что get * будет более подходящим?

Да, есть Phalcon\DI\Service объект, который представляет службу и разрешается при вызове в первый раз (если это общая служба) или разрешается каждый раз (если это не так). Как правило, вы хотите, чтобы все ваши службы были общими, в противном случае это часто становится узким местом, например, при разрешении адаптера для базы данных без общего доступа, который устанавливает соединение каждый раз, когда вы вызываете его…

PS: Обратите внимание, чтобы он работал так, как вы хотите с DbAdapter Вы можете сделать несколько вещей:

  1. Добавьте адаптер получения и возврата DI::getDefault()->getShared('db');
  2. Расширить Phalcon\DI\Injectable и установите DI при создании класса, чтобы он мог искать сервисы.
  3. Каждый раз, когда вам нужен адаптер, просто получите его от DI, как показано в первом варианте.
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]