Внедрение зависимостей в PHP (slim, php-di)
У меня есть приложение Slim Php (slim4), в которое я добавил Monolog для ведения журнала. Я добавляю логгер в приложение вот так:
$containerBuilder->addDefinitions([
LoggerInterface::class => function (ContainerInterface $c) {
$logger = new Logger('appname');
...
return $logger
Это отлично работает для внедрения регистратора в большинство моих классов, просто выполнив:
public function __construct(ContainerInterface $container = null, LoggerInterface $logger)
{
// I can use $logger here
Теперь я также хотел бы использовать регистратор в промежуточном программном обеспечении, таком как аутентификация. Я не понимаю, как я могу это сделать правильно. Я могу заставить это работать, добавив регистратор в качестве именованной записи в контейнер, например:
$containerBuilder->addDefinitions([
"LoggerInterface" => function (ContainerInterface $c) {
а затем передать его промежуточному программному обеспечению в качестве параметра конструктора, получив его обратно из контейнера:
$middlewares[] = new MyAuthentication(..., $container->get('LoggerInterface'));
Но это:
- а) разбивает инъекцию по имени класса для других классов
- б) очевидно не лучшая практика
Итак, как правильно внедрить этот регистратор в промежуточное ПО?
3 ответа
Без добавления LoggerInterface
в качестве именованной записи в контейнер, не могли бы вы просто ввести LoggerInterface
class напрямую к вашему промежуточному программному обеспечению через $container->get()
? IE вroutes.php
Функция приложения:
$container = $app->getContainer();
$app->add(new MiddleWare\MyAuthentication(..., $container->get(LoggerInterface::class)));
Короче говоря, я не думаю, что вы сможете автоматически подключать зависимости для промежуточного программного обеспечения, поскольку они должны быть созданы до добавления к маршрутизатору. Вам нужно будет явно ввести зависимость, как это предлагает @Woodrow, хотя я бы выбрал внедрение метода вместо внедрения конструктора для LoggerInterface, поскольку он будет придерживаться LoggerAwareInterface.
Вы можете позволить контейнеру внедрения зависимостей (PHP-DI) разрешить и внедрить все зависимости в ваше промежуточное ПО:
LoggerInterface::class => function (ContainerInterface $container) {
return new Logger('name');
},
Затем просто зарегистрируйте промежуточное ПО с именем класса:
$app->add(\MiddleWare\MyAuthentication::class);
(Вы не должны вставлять сам контейнер в промежуточное ПО)
Вот и все.