在 Symfony 中注入配置
Inject configuration in Symfony
我正在使用 Symfony 4,有一个配置文件需要以数组的形式注入到命令 App\Command\FooCommand
中。我在App\Kernel::configureContainer()
注册了一个自定义的DI扩展,用于验证自定义配置文件(为了开发方便,配置很大,在开发过程中经常更改)。命令的构造函数是 public function __construct(Foo $foo, array $config)
,我希望配置作为第二个参数。
现在如何将此配置放在那里?该文档说明了参数,但它不是参数。我正在考虑更改命令的定义并在 Extension::load
方法中添加此参数,如下所示:
class FooExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container)
{
$configuration = $this->getConfiguration($configs, $container);
$config = $this->processConfiguration($configuration, $configs);
//inject the configuration into the command
$fooCmdDef = $container->getDefinition(FooCommand::class);
$fooCmdDef->addArgument($config);
}
}
但最终出现错误
You have requested a non-existent service "App\Command\FooCommand".
但是该命令必须已自动注册为服务。
我做错了什么以及如何注入这个配置?
您无法访问 DI 扩展中的任何服务 Class 因为容器尚未编译。对于您的情况,创建一个 Compiler Pass 是很常见的,您可以在其中检索所需的服务并对其应用任何修改。
例如,您可以在容器扩展中创建一个关于存储配置的参数:
class FooExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container)
{
$configuration = $this->getConfiguration($configs, $container);
$config = $this->processConfiguration($configuration, $configs);
//create a container parameter
$container->setParameter('your_customized_parameter_name', $config);
}
}
然后在编译过程中检索您需要的内容,然后应用一些修改:
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
class YourCompilerPass implements CompilerPassInterface
{
/**
* {@inheritdoc}
*/
public function process(ContainerBuilder $container)
{
# retrieve the parameter
$config = $container->getParameter('your_customized_parameter_name');
# retrieve the service
$fooCmdDef = $container->getDefinition(FooCommand::class);
# inject the configuration
$fooCmdDef->addArgument($config);
# or you can also replace an argument
$fooCmdDef->replaceArgument('$argument', $config);
}
}
我正在使用 Symfony 4,有一个配置文件需要以数组的形式注入到命令 App\Command\FooCommand
中。我在App\Kernel::configureContainer()
注册了一个自定义的DI扩展,用于验证自定义配置文件(为了开发方便,配置很大,在开发过程中经常更改)。命令的构造函数是 public function __construct(Foo $foo, array $config)
,我希望配置作为第二个参数。
现在如何将此配置放在那里?该文档说明了参数,但它不是参数。我正在考虑更改命令的定义并在 Extension::load
方法中添加此参数,如下所示:
class FooExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container)
{
$configuration = $this->getConfiguration($configs, $container);
$config = $this->processConfiguration($configuration, $configs);
//inject the configuration into the command
$fooCmdDef = $container->getDefinition(FooCommand::class);
$fooCmdDef->addArgument($config);
}
}
但最终出现错误
You have requested a non-existent service "App\Command\FooCommand".
但是该命令必须已自动注册为服务。
我做错了什么以及如何注入这个配置?
您无法访问 DI 扩展中的任何服务 Class 因为容器尚未编译。对于您的情况,创建一个 Compiler Pass 是很常见的,您可以在其中检索所需的服务并对其应用任何修改。
例如,您可以在容器扩展中创建一个关于存储配置的参数:
class FooExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container)
{
$configuration = $this->getConfiguration($configs, $container);
$config = $this->processConfiguration($configuration, $configs);
//create a container parameter
$container->setParameter('your_customized_parameter_name', $config);
}
}
然后在编译过程中检索您需要的内容,然后应用一些修改:
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
class YourCompilerPass implements CompilerPassInterface
{
/**
* {@inheritdoc}
*/
public function process(ContainerBuilder $container)
{
# retrieve the parameter
$config = $container->getParameter('your_customized_parameter_name');
# retrieve the service
$fooCmdDef = $container->getDefinition(FooCommand::class);
# inject the configuration
$fooCmdDef->addArgument($config);
# or you can also replace an argument
$fooCmdDef->replaceArgument('$argument', $config);
}
}