Использование параметров в классе внедрения зависимостей

Дата обновления перевода 2023-08-25

Использование параметров в классе внедрения зависимостей

Вы уже видели, как использовать параметры конфигурации в сервис-контейнерах Symfony . Существуют специальные случаи, когда, например, вы хотите использовать параметр %kernel.debug%, чтобы заставить ваш пакет войти в режим отладки. Для такого случая нужно сделать больше работы, чтобы заставить систему понять значение параметра. По умолчаню, ваш параметр %kernel.debug% будет воспринят, как обычная строка. Рассмотрите следующий пример:

1
2
3
4
5
6
7
8
9
10
11
// inside Configuration class
$rootNode
    ->children()
        ->booleanNode('logging')->defaultValue('%kernel.debug%')->end()
        // ...
    ->end()
;

// внутри класса Расширения
$config = $this->processConfiguration($configuration, $configs);
var_dump($config['logging']);

Теперь, рассмотрите результаты внимательнее, чтобы увидеть это:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
my_bundle:
    logging: true
    # true, as expected

my_bundle:
    logging: '%kernel.debug%'
    # true/false (зависит от 2го параметра Kernel),
    # как ожидается, так как %kernel.debug% внутри конфигурации
    # оценивается перед тем, как передаётся расширению

my_bundle: ~
# передаёт строку "%kernel.debug%".
# Которая всегда считается true.
# Конфигуратор не знает ничего о том, что
# "%kernel.debug%" - это параметр.

Чтобы поддержать такой пример использования, класс Configuration должен быть внедрён с этим параметро через расширение, как показано далее:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
namespace App\DependencyInjection;

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

class Configuration implements ConfigurationInterface
{
    private bool $debug;

    public function __construct(private bool $debug)
    {
    }

    public function getConfigTreeBuilder(): TreeBuilder
    {
        $treeBuilder = new TreeBuilder('my_bundle');

        $treeBuilder->getRootNode()
            ->children()
                // ...
                ->booleanNode('logging')->defaultValue($this->debug)->end()
                // ...
            ->end()
        ;

        return $treeBuilder;
    }
}

И установите его в конструкторе Configuration через класс Extension:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
namespace App\DependencyInjection;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;

class AppExtension extends Extension
{
    // ...

    public function getConfiguration(array $config, ContainerBuilder $container): Configuration
    {
        return new Configuration($container->getParameter('kernel.debug'));
    }
}

Tip

Существуют экземпляры использования %kernel.debug% в рамках класса Configurator, например, в TwigBundle. Однако это так, потому что значение параметра по умолчанию устанавливается классом Расширения.