config.yml中的依赖注入

时间:2014-12-12 22:46:41

标签: symfony

我有两个服务,我想从config.yml传递我的参数

我的config.yml

parameters:
    MyService.class:      Acme\UserBundle\Services\sendEmail
    MyService.arguments:  @mailer

    NewUserListener.class:  Acme\UserBundle\Event\NewUserListener
    NewUserListener.arguments:  @MyService

我的service.yml内包

services:
MyService:
    class:        %MyService.class%
    arguments:    [%MyService.arguments%]

NewUserListener:
    class: %NewUserListener.class%
    arguments:    [%NewUserListener.arguments%]
    tags:
        - { name: kernel.event_listener, event: new.user, method: sendEmailToUsers }

我收到了错误

  

您无法转储包含引用的参数的容器   其他服务

我的问题是:

  • 如何从config.yml注入我的参数?
  • 我在哪里可以找到"全球服务"喜欢@mailer?我找不到文档

2 个答案:

答案 0 :(得分:1)

您无法在参数中引用服务。您应该将%MyService.arguments%替换为@mailer

要查找所有可用服务,请运行php app/console container:debug

答案 1 :(得分:1)

这有点复杂!

首先,您必须声明您的默认服务(我更改了所有名称以符合Symfony2的约定):

# resources/config/services.yml

services:
    my_own.service.default.class: Acme\UserBundle\Services\sendEmail
    my_own.user_listener.default.class: Acme\UserBundle\Event\NewUserListener

services:
    my_own.service.default:
        class: %my_own.service.default.class%
        arguments: [@mailer]

    my_own.user_listener:
        class: %my_own.user_listener.class%
        arguments: [@my_own.service]
        tags:
            - { name: kernel.event_listener, event: new.user, method: sendEmailToUsers }

我们将define some configuration for your bundle以便更改已使用的服务:

namespace My\OwnBundle\DependencyInjection;

use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;

/**
 * This is the class that validates and merges configuration from your app/config files
 *
 * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html#cookbook-bundles-extension-config-class}
 */
class Configuration implements ConfigurationInterface
{
    /**
     * {@inheritDoc}
     */
    public function getConfigTreeBuilder()
    {
        $treeBuilder = new TreeBuilder();
        $rootNode = $treeBuilder->root('my_own');

        // Here you should define the parameters that are allowed to
        // configure your bundle. See the documentation linked above for
        // more information on that topic.
        $rootNode
            ->children()
                ->scalarNode('service')->defaultValue('my_own.service.default')->end()
                ->scalarNode('user_listener')->defaultValue('my_own.user_listener.default')->end()
            ->end();

        return $treeBuilder;
    }
}

请注意,默认情况下,我们会在捆绑包中使用上面定义的默认服务。

您现在可以使用以下内容更改您的服务(例如在app/config.yml中):

# app/config.yml

my_own:
    service: my_other.service
    user_listener: my_other.user_listener

当然,您可以根据需要在捆绑包或其他捆绑包中定义服务my_other.servicemy_other.user_listener

现在我们必须告诉如何使用此配置来获取所需的服务:

namespace My\OwnBundle\DependencyInjection;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;

/**
 * This is the class that loads and manages your bundle configuration
 *
 * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html}
 */
class MyOwnExtension extends Extension
{
    /**
     * {@inheritDoc}
     */
    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');

        $container->setAlias('my_own.service', $config['service']);
        $container->setAlias('my_own.user_listener', $config['user_listener']);
    }
}

最后,在您的其余代码中,您必须在代码中使用别名服务my_own.servicemy_own.user_listener

// In one of your controller:
$this->container->get('my_own.service');
/* or directly */ $this->get('my_own.service'); // if your controller is a child of the framework bundle class `Controller`.