【发布时间】:2018-12-12 01:12:29
【问题描述】:
我有一个 Sumfony 4.3 命令,它处理一些数据并循环通过多个“处理器”来进行处理。代码使用工厂(自动装配),然后实例化命令。
use App\Entity\ImportedFile;
use App\Service\Processor\Processor;
class Factory implements FactoryInterface
{
/** @var array */
private $processors;
/** @var TestClausesInterface */
private $testClauses;
private $em;
private $dataSetProvider;
private $ndviFromNasaService;
private $archivalHashService;
private $mailer;
private $projectDir;
public function __construct(
TestClausesInterface $testClauses,
ValidProcessorList $processors,
EntityManagerInterface $em,
DataSetProvider $dataSetProvider,
NDVIFromNasaService $ndviFromNasaService,
ArchivalHashService $archivalHashService,
\Swift_Mailer $mailer,
$projectDir)
{
$this->processors = $processors;
$this->testClauses = $testClauses;
$this->em = $em;
$this->dataSetProvider = $dataSetProvider;
$this->ndviFromNasaService = $ndviFromNasaService;
$this->archivalHashService = $archivalHashService;
$this->mailer = $mailer;
$this->projectDir = $projectDir;
}
public function findProcessorForFile(ImportedFile $file)
{
...
if ($found){
$candidates = $this->recursive_scan( $this->projectDir.'/src/Processor');
foreach ($candidates as $candidate){
if (substr($candidate,0,strlen('Helper')) === 'Helper'){
continue;
}
try {
$candidate = str_replace($this->projectDir.'/src/Processor/', '', $candidate);
$candidate = str_replace('/','\\', $candidate);
$testClassName = '\\App\\Processor\\'.substr( $candidate, 0, -4 );
/* @var Processor $test */
if (!strstr($candidate, 'Helper')) {
$test = new $testClassName($this->testClauses, $this->em, $this->dataSetProvider, $this->ndviFromNasaService, $this->archivalHashService, $this->mailer, $this->projectDir);
}
但我仍然必须:
- 自动装配 Factory 和 Processor 顶级类中的所有参数
- 将所有参数按正确顺序传递给处理器
我有大约 70 个处理器子类。它们都使用EntityInterface,但只有少数使用SwiftMailer 和其他依赖项。
由于我正在添加仅供少数处理器使用的服务,因此我正在寻找一种仅在处理器级别自动装配这些参数的方法。理想情况下,也无需向 services.yml 添加服务定义
总而言之,我希望能够向Processor 的任何子类添加依赖项,即使它是其他子类的父类并自动注入依赖项。
【问题讨论】:
-
不是肯定的,但可能是 ProcessServiceLocator 而不是流程工厂。基本上,流程定位器将包含可用流程服务的列表。 symfony.com/doc/current/service_container/…
-
Symfony 自动连接将我作为参数放入构造函数中的任何内容。我想在这里实现同样的目标。当我向处理器类的构造函数添加参数时,我希望注入此服务,否则不会。然后我仍然会从工厂注入实体管理器,但这与解决方案无关
-
我想差不多了。连接服务定位器似乎工作。我在数据库表中使用文件前缀间接确定哪个处理器处理文件,因此我使用 strval($type->getId()) 与公共静态函数 getDefaultIndexName() 匹配。但是服务定位器没有找到处理器,当我调试时,我看不到我的 getDefaultIndexName() 返回值是如何在任何地方索引的
标签: php symfony dependency-injection symfony4 symfony-dependency-injection