首页 > 解决方案 > 无法在命令类中获得服务。Symfony 3.4

问题描述

我需要通过 autowire 连接命令行上的服务。

我使用 symfony 3.4,但我不明白如何正确注册此设置。我在 app/config/services.yml 中有以下设置:

services:
    _defaults:
        autowire: true
        autoconfigure: true
        public: false

    CoreBundle:
        resource: '../../src/CoreBundle/*'
        # you can exclude directories or files
        # but if a service is unused, it's removed anyway
        exclude: '../../src/CoreBundle/{Entity,Repository}'

在命令中,我试图覆盖命令中的构造函数方法。我正在尝试通过构造函数获取服务

<?php

namespace CoreBundle\Command;

use Symfony\Component\Console\Command\Command;
use CoreBundle\Service\ObjectTypeService;

class TestCommand extends Command
{
    private $objectSevice;

    public function __construct(ObjectTypeService $objectSevice) 
    {
        $this->objectSevice = $objectSevice;
        parrent::_construct();
    }

    protected function configure()
    {
        $this
            ->setName('core:test')
            ->setDescription('');
    }
    
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        //some code…
    }
}

我得到错误:

命令“core:test”未定义。

你的意思是其中之一吗?

核心:检查

这不适用于实体管理器:

<?php

namespace CoreBundle\Command;

use Symfony\Component\Console\Command\Command;
use CoreBundle\Service\ObjectTypeService;
use Doctrine\ORM\EntityManager;

class TestCommand extends Command
{
    private $em;

    public function __construct(EntityManager $em)
    {
        $this->em = $em;

        parent::__construct();
    }

    //some code…
}

这是我在为依赖注入指定参数类型时遇到的错误。如果我们删除这些论点,它就会起作用。

<?php

namespace CoreBundle\Command;

use Symfony\Component\Console\Command\Command;
use CoreBundle\Service\ObjectTypeService;
use Doctrine\ORM\EntityManager;

class TestCommand extends Command
{
    public function __construct()
    {
        parent::__construct();
    }

    //some code…
}

我不知道如何正确连接 autowire 以便它在命令类中工作

标签: symfonysymfony-console

解决方案


Symfony's documentation says:

If you’re using the default services.yml configuration, the command class will automatically be registered as a service

So there's no need to register the commands in your config.

If you want to use Dependency Injection, extend your command from Symfony\Component\Console\Command\Command instead of Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand:

use Symfony\Component\Console\Command\Command;

class WarehouseExportStockCommand extends Command
{
    private $objectSevice;

    public function __construct(ObjectTypeService $objectSevice) 
    {
        $this->objectSevice = $objectSevice;
        parrent::_construct();
    }
    
    // ...
}

And you might want to follow the convention of lower case command names: core:test:command. I'm not sure if camelCase command names can case problems, but following Symfony's convention is usually a good idea.


推荐阅读