Symfony:无法访问bundle构造函数内的服务



如何访问Bundle构造函数内部的服务?我正在尝试创建一个系统,在这个系统中,主题捆绑包可以自动向主题服务注册,参见下面的小示例(解决方案越简单越好):

<?php
namespace OrganizationThemeBasicBundle;
use SymfonyComponentHttpKernelBundleBundle;
class ThemeBasicBundle extends Bundle
{
    public function __construct() {
        $themes = $this->get('organization.themes');
        $themes->register(new OrganizationThemeBasicBundleEntityTheme(__DIR__));
    }
}

然而,$this->get不起作用,这可能是因为无法保证所有捆绑包都已注册,是否有任何捆绑包后注册"挂钩"可以代替我使用?有什么特殊的方法名称可以添加到所有bundle实例化后执行的bundle类中吗?

服务类如下所示:

<?php
namespace OrganizationThemeBasicBundle;
use OrganizationThemeBasicBundleEntityTheme;
class ThemeService
{
    private $themes = array();
    public function register(Theme $theme) {
        $name = $theme->getName();
        if (in_array($name, array_keys($this->themes))) {
            throw new Exception('Unable to register theme, another theme with the same name ('.$name.') is already registered.');
        }
        $this->themes[$name] = $theme;
    }
    public function findAll() {
        return $this->themes;
    }
    public function findByName(string $name) {
        $result = null;
        foreach($this->themes as $theme) {
            if ($theme->getName() === $name) {
                $result = $theme;
            }
        }
        return $result;
    }
}

不能访问服务容器是正常的,因为服务还没有编译。要将标记的服务注入该捆绑包,您需要创建一个新的编译器通行证

要创建编译器传递,它需要实现CompilerPassInterface。

将类放在捆绑包的DependencyInjection/Compiler文件夹中。

use SymfonyComponentDependencyInjectionCompilerCompilerPassInterface;
use SymfonyComponentDependencyInjectionContainerBuilder;
class CustomCompilerPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container)
    {
        if ($container->has('organization.themes')) {
            $container->getDefinition('organization.themes')->addMethodCall('register', array(new OrganizationThemeBasicBundleEntityTheme(__DIR__)));
        }
    }
}

然后重写bundle定义类的构建方法。

class ThemeBasicBundle extends Bundle
{
    public function build(ContainerBuilder $container)
    {
        $container->addCompilerPass(new CustomCompilerPass());
    }
}

一些链接:

http://symfony.com/doc/current/components/dependency_injection/compilation.htmlhttp://symfony.com/doc/current/cookbook/service_container/compiler_passes.htmlhttp://symfony.com/doc/current/components/dependency_injection/tags.html

尝试它可以工作:):

<?php
namespace OrganizationThemeBasicBundle;
use SymfonyComponentHttpKernelBundleBundle;
use SymfonyComponentDependencyInjectionContainerBuilder;
class ThemeBasicBundle extends Bundle
{
    public function build(ContainerBuilder $container)
    {
        parent::build($container);
        $themes = $container->get('organization.themes');
        $themes->register(new OrganizationThemeBasicBundleEntityTemplate(__DIR__));
    }
}

最新更新