如何访问Bundle构造函数中的服务?我正在尝试创建一个系统,其中主题包可以使用主题服务自动注册,请参阅下面的小示例(更简单的解决方案更好):
<?php
namespace Organization\Theme\BasicBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class ThemeBasicBundle extends Bundle
{
public function __construct() {
$themes = $this->get('organization.themes');
$themes->register(new Organization\Theme\BasicBundle\Entity\Theme(__DIR__));
}
}
但是,$ this-&gt; get不起作用,这可能是因为无法保证所有捆绑包已经注册,是否有任何可以使用的邮件包注册“挂钩”?是否有任何特殊的方法名称可以添加到bundle类中,并在实例化所有bundle之后执行?
服务类如下所示:
<?php
namespace Organization\Theme\BasicBundle;
use Organization\Theme\BasicBundle\Entity\Theme;
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;
}
}
答案 0 :(得分:3)
您无法访问服务容器是正常的,因为尚未编译服务。 要将标记服务注入到该包中,您需要创建一个新的编译器传递。
要创建编译器传递,它需要实现CompilerPassInterface。
将该类放在bundle的DependencyInjection / Compiler文件夹中。
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class CustomCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
if ($container->has('organization.themes')) {
$container->getDefinition('organization.themes')->addMethodCall('register', array(new Organization\Theme\BasicBundle\Entity\Theme(__DIR__)));
}
}
}
然后覆盖包定义类的构建方法。
class ThemeBasicBundle extends Bundle
{
public function build(ContainerBuilder $container)
{
$container->addCompilerPass(new CustomCompilerPass());
}
}
一些链接:
http://symfony.com/doc/current/components/dependency_injection/compilation.html http://symfony.com/doc/current/cookbook/service_container/compiler_passes.html http://symfony.com/doc/current/components/dependency_injection/tags.html
答案 1 :(得分:2)
尝试它可以工作:):
<?php
namespace Organization\Theme\BasicBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class ThemeBasicBundle extends Bundle
{
public function build(ContainerBuilder $container)
{
parent::build($container);
$themes = $container->get('organization.themes');
$themes->register(new Organization\Theme\BasicBundle\Entity\Template(__DIR__));
}
}