Как использовать сервисы, определенные в PHP-DI в services.yaml Symfony?
Я пишу приложение, которое имеет структуру приложения Symfony и некоторые функциональные возможности Symfony, но должно быть отделено от фреймворка, насколько это возможно. Поэтому вместо DI фреймворка я использую PHP-DI.
Теперь мне нужно Symfony's EventDispatcher
(горькая пилюля для моей отделенной от фреймворка архитектуры, но в любом случае...). Моя проблема в том, что я не получаю ссылки от services.yaml
к контейнеру PHP-DI работает - и мои слушатели не привязаны к EventDispatcher
,
Как использовать сервисы контейнера PHP-DI в services.yaml
(особенно для EventDispatcher
если есть какая то конкретика)?
Вот некоторый код:
services.yaml
(полностью)
parameters:
services:
_defaults:
autowire: true
autoconfigure: true
public: false
# events
# App\Process\SystemEventHandler: <-- No errors, but also no effect.
@system.event_handler:
tags:
- { name: system.event_handler, event: general.user_message_received, method: handle }
- { name: system.event_handler, event: xxx.foo, method: handle }
- { name: system.event_handler, event: yyy.foo, method: handle }
- { name: system.event_handler, event: zzz.foo, method: handle }
App\Kernel
(полностью)
namespace App;
use DI\Bridge\Symfony\Kernel as PhpDIBridgeSymfonyKernel;
use DI\Container;
use DI\ContainerBuilder as PhpDiContainerBuilder;
use Exception;
use Psr\Container\ContainerInterface;
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\Config\Exception\FileLoaderLoadException;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Routing\RouteCollectionBuilder;
class Kernel extends PhpDIBridgeSymfonyKernel
{
use MicroKernelTrait;
const CONFIG_EXTS = '.{php,xml,yaml,yml}';
public function getCacheDir()
{
return $this->getProjectDir().'/var/cache/'.$this->environment;
}
public function getLogDir()
{
return $this->getProjectDir().'/var/log';
}
public function registerBundles()
{
$contents = require $this->getProjectDir() . '/config/bundles.php';
foreach ($contents as $class => $envs) {
if (isset($envs['all']) || isset($envs[$this->environment])) {
yield new $class();
}
}
}
/**
* @param ContainerBuilder $container
* @param LoaderInterface $loader
* @throws Exception
*/
protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader)
{
$container->addResource(new FileResource($this->getProjectDir().'/config/bundles.php'));
// Feel free to remove the "container.autowiring.strict_mode" parameter
// if you are using symfony/dependency-injection 4.0+ as it's the default behavior
$container->setParameter('container.autowiring.strict_mode', true);
$container->setParameter('container.dumper.inline_class_loader', true);
$confDir = $this->getProjectDir().'/config';
$loader->load($confDir.'/{packages}/*'.self::CONFIG_EXTS, 'glob');
$loader->load($confDir.'/{packages}/'.$this->environment.'/**/*'.self::CONFIG_EXTS, 'glob');
$loader->load($confDir.'/{services}'.self::CONFIG_EXTS, 'glob');
$loader->load($confDir.'/{services}_'.$this->environment.self::CONFIG_EXTS, 'glob');
}
/**
* @param RouteCollectionBuilder $routes
* @throws FileLoaderLoadException
*/
protected function configureRoutes(RouteCollectionBuilder $routes)
{
$confDir = $this->getProjectDir().'/config';
$routes->import($confDir.'/{routes}/*'.self::CONFIG_EXTS, '/', 'glob');
$routes->import($confDir.'/{routes}/'.$this->environment.'/**/*'.self::CONFIG_EXTS, '/', 'glob');
$routes->import($confDir.'/{routes}'.self::CONFIG_EXTS, '/', 'glob');
}
/**
* @param PhpDiContainerBuilder $builder
* @return Container|ContainerInterface
* @throws Exception
*/
protected function buildPHPDIContainer(PhpDiContainerBuilder $builder)
{
// Configure your container here
// http://php-di.org/doc/container-configuration.html
$builder->addDefinitions($this->getProjectDir() . '/config/dependencies/common.php');
return $builder->build();
}
}
/config/dependencies/common.php
(файл с зависимостями, соответствующая выписка)
...
return [
FooServiceInterface::class => DI\autowire(FooBService::class),
BarServiceInterface::class => DI\autowire(BarService::class),
...
EntityManagerInterface::class => function () {
...
},
'process_handler.xxx' => DI\autowire(XxxHandler::class),
'process_handler.yyy' => DI\autowire(YyyHandler::class),
'process_handler.zzz' => DI\autowire(ZzzHandler::class),
EventHandlerInterface::class => DI\factory(function(ContainerInterface $container) {
return new SystemEventHandler(
$container->get('process_handler.xxx'),
$container->get('process_handler.yyy'),
$container->get('process_handler.zzz')
);
}),
'system.event_handler' => DI\get(EventHandlerInterface::class),
EventDispatcherInterface::class => DI\get('event_dispatcher'),
];