Can't get service in command class. Symfony 3.4

824 views Asked by At

I need to connect the services on the command line via autowire.

I use symfony 3.4 and I do not understand how to correctly register the settings for this. I have the following setting in 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}'

In a command, I am trying to override the constructor method in command. I am trying to get a service through the constructor

<?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…
    }
}

And i get error:

Command "core:test" is not defined.

Did you mean one of these?

core:check

And this doesn't work with entity manager:

<?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…
}

This is the error I get when I specify the argument type for dependency injection. If we remove these arguments, it works.

<?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…
}

I do not know how to properly connect autowire so that it works inside the command class

1

There are 1 answers

3
Stephan Vierkant On

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.