我一直在使用symfony/console来制作命令并注册它们,一切都很好:
bin/console:
#!/usr/bin/env php
<?php
require_once __DIR__ . '/../vendor/autoload.php';
use App\Commands\LocalitiesCommand;
use Symfony\Component\Console\Application;
$app = new Application();
$app->add(new LocalitiesCommand(new LocalitiesGenerator()));
$app->run();
src/Commands/LocalitiesCommand.php:
<?php
declare(strict_types=1);
namespace App\Commands;
use App\LocalitiesGenerator;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
final class LocalitiesCommand extends Command
{
protected static $defaultName = 'app:generate-localities';
public function __construct(private LocalitiesGenerator $localitiesGenerator)
{
parent::__construct();
}
protected function configure(): void
{
$this
->setDescription('Generate localities.json file')
->setHelp('No arguments needed.');
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$this->localitiesGenerator->generateJsonLocalities();
$output->writeln("File localities.json generated!");
return Command::SUCCESS;
}
}
现在我想使用symfony/dependency-injection自动注入服务,我正在阅读文档并做了一些更改:
新建bin/console:
#!/usr/bin/env php
<?php
require_once __DIR__ . '/../vendor/autoload.php';
use App\Commands\LocalitiesCommand;
use Symfony\Component\Console\Application;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\Config\FileLocator;
$container = new ContainerBuilder();
$loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/src/config'));
$loader->load('services.yaml');
$container->compile();
$app = new Application();
$app->add(new LocalitiesCommand());
$app->run();
config/services.yaml:
services:
_defaults:
autowire: true
autoconfigure: true
public: false
但是当我示例化我的命令时,仍然要求我在构造函数中添加我的服务。为什么它不起作用?
2条答案
按热度按时间lf3rwulv1#
首先,让我们澄清一个误解:
但是当我示例化我的命令时,仍然要求我在构造函数中添加我的服务。为什么它不起作用?
如果你调用
new Foo()
,那么你将不再获得自动连接DI的好处。如果你想使用自动连接和自动依赖注入,你需要让Symfony为你工作。当你调用new
时,你正在手动示例化对象,你需要自己处理DI。如果不这样做,你怎么能做到这一点呢?
首先,
composer.json
带有基本依赖项和自动加载器声明:完整的目录结构最终将是这样的:
现在,每个部分:
包含所有依赖项和自动加载器的
composer.json
文件:前端控制器脚本,即运行应用程序的文件(在我的例子中是
app
):项目的服务容器配置:
一个
FooCommand
类:以上依赖于
App\Text\Reverser
服务,它将由DI组件自动为我们注入:在安装并转储自动加载器之后,通过执行
php app
(1),我可以使用foo
命令(2):我可以执行
php app foo
,并且使用其注入的依赖关系正确执行命令:一个独立的Symfony控制台应用程序,具有最小的依赖性和自动依赖注入。
(All一个非常相似的例子的代码,here)。
6pp0gazn2#
无需疯狂的设置,只需将命令添加为
CliApplication
依赖项并将其注册到构造函数中: