SF 3.4 在服务中注入捆绑配置

SF 3.4 inject bundle config in services

使用 Symfony 3.4,我只是尝试一个新包的简单案例(名称:APiToolBundle)。

这里是src/ApiToolBundle/Resources/config/config.yml的内容:

imports:
    - { resource: parameters.yml }

api_tool:
    api_url: %myapi_url%
    api_authorization_name: 'Bearer'

此文件由 ApiToolBundleExtension 加载:

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');
}

我也设置了配置文件:

class Configuration implements ConfigurationInterface
{
    public function getConfigTreeBuilder()
    {
        $treeBuilder = new TreeBuilder();
        $rootNode = $treeBuilder->root('production_tool');

        $rootNode
            ->children()
            ->scalarNode('api_url')->defaultValue('')->end()
            ->scalarNode('api_authorization_name')->defaultValue('')->end()
            ->end()
        ;

        return $treeBuilder;
    }
}

但是我只想将配置参数绑定到我的一项服务:

# src/ApiToolBundle/Resources/config/services.yml
ApiToolBundle\Service\MyApi:
  bind:
    $apiUrl: '%api_tool.api_url%'

我基于此文档:https://symfony.com/doc/3.4/bundles/configuration.html

但我不确定是否理解所有内容,因为他们以其他方式谈论 mergin ...我是否需要做其他事情来加载我自己的 bundle 配置文件?

这确实有点棘手。捆绑包配置与您在服务配置中使用的参数不同(即使在您的配置中您也可以定义服务,起初看起来有点奇怪)。这也是为什么 Symfony 在版本 4 中不鼓励在应用程序内部使用语义配置,不使用 bundle & 配置,而是直接使用参数和服务的原因之一。

您需要将配置映射到参数或直接将它们注入到您需要它们的服务中,以防您不希望它们对其他服务公开可用或使用 getParameter。您可以在您有权访问 ContainerBuilder 的扩展中执行此操作。

例如,请参阅 FrameworkExtension,其中您具有更改容器的大型配置:https://github.com/symfony/symfony/blob/v3.4.30/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php#L194-L196

在您的情况下,它可能看起来像这样:

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');

    # Below is the new part, the rest is copied from your question

    # If you only want to use the configuration values internally in your services:
    $container->getDefinition('ApiToolBundle\Service\MyApi')->setArgument(
        0 # Offset of the argument where you want to use the api url
        $config['api_url']
    );

    # If you want to make the values publicly available as parameters:
    $container->setParameter('api_tool.api_url', $config['api_url']);
}