misha
misha

Reputation: 301

Symfony 4 custom container aware command error

I am trying to create custom command in Symfony 4 project

class AppOauthClientCreateCommand extends ContainerAwareCommand
{

   protected function configure()
   {
     $this
        ->setName('app:oauth-client:create')
        ->setDescription('Create a new OAuth client');
   }

   protected function execute(InputInterface $input, OutputInterface $output)
   {
    $clientManager = $this->getContainer()->get('fos_oauth_server.client_manager.default');
    $client = $clientManager->createClient();
    $client->setAllowedGrantTypes(array(OAuth2::GRANT_TYPE_USER_CREDENTIALS));
    $clientManager->updateClient($client);

    $output->writeln(sprintf('client_id=%s_%s', $client->getId(), $client->getRandomId()));
    $output->writeln(sprintf('client_secret=%s', $client->getSecret()));
   }
}

I am getting following error when I try to run this command

The "fos_oauth_server.client_manager.default" service or alias has been removed or inlined when the container was compiled. You should either
make it public, or stop using the container directly and use dependency injection instead.

How do I make vendor service public or am I missing something in command configurations?

Upvotes: 1

Views: 3146

Answers (2)

VladRia
VladRia

Reputation: 1587

The problem is that all services are private by deafault since Symfony 4. In fact it is not possible to get a private service using get method of the service container.

You should avoid injecting the entire contanier in your services (or commands by extending ContainerAwareCommand). Instead you should inject only the needed services:

class AppOauthClientCreateCommand
{
   /**
    * @var ClientManagerInterface
    */
   private $clientManager;

   public function __construct(ClientManagerInterface $clientManager)
   {
       $this->clientManager = $clientManager;
   }

   protected function configure()
   {
       ...
   }

   protected function execute(InputInterface $input, OutputInterface $output)
   {
        $client = $this->clientManager->createClient();
        ...
   }
}

If ClientManagerInterface is not autowired then you must configure your AppOauthClientCreateCommand with proper dependency in your services.yaml. Something like:

services:
    App\Command\AppOauthClientCreateCommand:
        arguments:
            $clientManager: "@fos_oauth_server.client_manager.default"

Hope this helps.

Upvotes: 3

Alister Bulman
Alister Bulman

Reputation: 35139

You will need to check the ./bin/console debug:autowiring command's output for the appropriate interface to use 'fos_oauth_server.client_manager.*' in the constructor. Autowiring should already be setup to allow for the container to recognise and insert it from there.

This will require FosOauthServer support for SF4 - and in the constructor remember to also call parent::__construct(); to properly setup the command. You can do that and still use the ContainerAwareCommand to ->get() other things from the container - but you will likely move away from that over time.

Upvotes: 1

Related Questions