我的应用程序包含多个名为HelloWorldAdminBundle
,HelloWorldUserBundle
,HelloWorldDemoBundle
的包。这会产生类似hello_world_demo
,hello_world_user
和hello_world_demo
的配置根。我希望我的捆绑包的配置根目录是helloworld_demo
,helloworld_user
和helloworld_admin
。那时我不得不提到这不是一个技术问题,而是一个美学问题。
我试图实现自定义扩展并在Bundle中注册它:
public function build(ContainerBuilder $container)
{
parent::build($container);
$container->registerExtension(new HelloworldDemoExtension());
}
扩展名:
...
class HelloworldDemoExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
}
public function getAlias()
{
return 'hello_world_demo';
}
}
最后是配置:
...
class Configuration implements ConfigurationInterface
{
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('helloworld_demo');
...
return $treeBuilder;
}
}
我按照说明How to expose a Semantic Configuration for a Bundle,但是当我向config.yml
添加项目时,我收到以下错误:
There is no extension able to load the configuration for "helloworld_demo"
答案 0 :(得分:3)
我找到了解决问题的方法。它完全按照我在问题中描述的那样工作,但是,默认扩展名(包含名称)必须。
我现在有一个空的,但现有的扩展名为HelloWorldDemoExtension(别名为hello_world_demo
,另外我添加了DemoExtension(别名为helloworld_demo
)并且它可以正常工作。
答案 1 :(得分:3)
我通过覆盖Symfony\Component\HttpKernel\Bundle\Bundle#getContainerExtension()
来解决这个问题。
此方法会自动创建并返回ExtensionInterface
的实例,并检查扩展程序的别名(您可以在扩展类中实现getAlias
指定,如Carlos Granados'所述)符合命名惯例。
因此,通过覆盖bundle类中的getContainerExtension()
方法,并简单地返回扩展类的实例,您可以绕过检查和LogicException
。
这是你的bundle类的样子:
<?php
namespace HelloWorld\Bundle\UserBundle;
use HelloWorld\Bundle\UserBundle\DependencyInjection\HelloWorldUserExtension;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class HelloWorldUserBundle extends Bundle
{
public function getContainerExtension()
{
if (null === $this->extension) {
$this->extension = new HelloWorldUserExtension();
}
return $this->extension;
}
}
当然,不要忘记将其添加到您的扩展程序中:
/**
* The extension alias
*
* @return string
*/
public function getAlias()
{
return 'helloworld_user';
}
警告:我不确定为何将此检查添加到getContainerExtension()
方法中。可能有一个非常有效的原因,并且在执行上述步骤时可能会遇到问题。但是,到目前为止我没有遇到任何问题。
修改:另请参阅:Symfony2: Some things I don't like about Bundles。这篇博客文章提供了与我的答案相同的解决方案。另请参阅this pull request以获取Symfony的文档,该文档也描述了相同的方法。这让我相信这样做是安全的,而不必期待副作用。
答案 2 :(得分:0)
正如documentation所说:
创建扩展程序时,请遵循以下简单约定:
- 扩展名必须存储在DependencyInjection子命名空间中;
- 扩展名必须以包名称命名,并以Extension为后缀(AcmeHelloExtension for AcmeHelloBundle);
- 扩展程序应提供XSD架构。
我真的不知道您是否需要定义自己的build
和getAlias
方法。如果需要,那么getAlias
方法应该返回与在根节点中定义的值相同的值。因此,它应该helloworld_demo
而不是hello_world_demo
答案 3 :(得分:0)
从书中 “在这种情况下,扩展类还必须实现一个getAlias()方法,并返回一个以bundle命名的唯一别名(例如acme_hello)。这是必需的,因为类名不符合标准,以Extension结尾。 此外,只有当用户在至少一个配置文件中指定acme_hello别名时,才会调用扩展的load()方法。 “
所以,这个别名是根配置名称。将您的代码更改为
public function getAlias()
{
return 'helloworld_demo';
}
它应该可行