osm*_*osm 34 console dependency-injection symfony
我正在编写一个开源应用程序使用一些Symfony组件,并使用Symfony Console组件与shell进行交互.
但是,我需要注入依赖项(在所有命令中使用),如Logger,Config对象,Yaml解析器......我通过扩展Symfony\Component\Console\Command\Command类解决了这个问题.但这使得单元测试变得更难,而且看起来不正确.
我怎么解决这个问题?
Ise*_*ngo 26
从Symfony 4.2开始,不推荐使用ContainerAwareCommand.请改用DI.
namespace App\Command;
use Symfony\Component\Console\Command\Command;
use Doctrine\ORM\EntityManagerInterface;
final class YourCommand extends Command
{
/**
* @var EntityManagerInterface
*/
private $entityManager;
public function __construct(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
parent::__construct();
}
protected function execute(InputInterface $input, OutputInterface $output)
{
// YOUR CODE
$this->entityManager->persist($object1);
}
}
Run Code Online (Sandbox Code Playgroud)
小智 23
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
Run Code Online (Sandbox Code Playgroud)
从ContainerAwareCommand扩展Command类并获取服务$this->getContainer()->get('my_service_id');
oro*_*edd 17
最好不要注入容器本身,而是将容器中的服务注入到对象中.如果您正在使用Symfony2的容器,那么您可以执行以下操作:
MyBundle/Resources/config/services(或者您决定放置此文件的位置):
...
<services>
<service id="mybundle.command.somecommand" class="MyBundle\Command\SomeCommand">
<call method="setSomeService">
<argument type="service" id="some_service_id" />
</call>
</service>
</services>
...
Run Code Online (Sandbox Code Playgroud)
然后你的命令类应如下所示:
<?php
namespace MyBundle\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use The\Class\Of\The\Service\I\Wanted\Injected;
class SomeCommand extends Command
{
protected $someService;
public function setSomeService(Injected $someService)
{
$this->someService = $someService;
}
...
Run Code Online (Sandbox Code Playgroud)
我知道你说你没有使用依赖注入容器,但是为了从@ramon实现上述答案,你必须使用它.至少这种方式可以对您的命令进行适当的单元测试.