首页 文章

Symfony 4自定义容器感知命令错误

提问于
浏览
1

我正在尝试在Symfony 4项目中创建自定义命令

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()));
   }
}

我尝试运行此命令时收到以下错误

编译容器时,“fos_oauth_server.client_manager.default”服务或别名已被删除或内联 . 您应该将其公开,或者直接停止使用容器并改为使用依赖注入 .

如何使供应商服务公开或我在命令配置中遗漏了什么?

2 回答

  • 2

    问题是,自Symfony 4以来,所有服务都是私有的 . 实际上,使用服务容器的 get 方法无法获得私有服务 .

    您应该避免在服务中注入整个contanier(或通过扩展 ContainerAwareCommand 来命令) . 相反,您应该只注入所需的服务:

    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();
            ...
       }
    }
    

    如果 ClientManagerInterface 未自动装配,则必须在services.yaml中配置 AppOauthClientCreateCommand 具有适当的依赖关系 . 就像是:

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

    希望这可以帮助 .

  • 1

    您需要在构造函数中检查 ./bin/console debug:autowiring 命令's output for the appropriate interface to use ' fos_oauth_server.client_manager . *' . 应该已经设置自动装配以允许容器识别并从那里插入它 .

    这将需要FosOauthServer支持SF4 - 并且在构造函数中记得也要调用 parent::__construct(); 来正确设置命令 . 你可以这样做,仍然使用ContainerAwareCommand来容器中的其他东西 - 但是你可能会随着时间的推移而远离它 .

相关问题