2

我正在使用 Symfony 4,并且有一个配置文件需要以App\Command\FooCommand数组的形式注入到命令中。我在 注册了一个自定义 DI 扩展App\Kernel::configureContainer(),用于验证自定义配置文件(为了开发方便,配置很大,在开发过程中会经常更改)。该命令的构造函数是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);
    }
}

但它以错误结束

您请求了一个不存在的服务“App\Command\FooCommand”。

但是,该命令必须已自动注册为服务。

我在做什么错以及如何注入此配置?

4

1 回答 1

1

您无法访问 DI 扩展类中的任何服务,因为该容器尚未编译。对于您的情况,通常创建一个编译器通行证,您将能够在其中检索所需的服务并对其应用任何修改。

例如,您可以在存储配置的容器扩展中创建一个参数:

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);
    }
}
于 2018-01-05T17:35:00.413 回答