我无法理解Dependency Injection如何在SF 4.3和PHP 7.2中用于自定义服务
在控制器中,此简单代码转储正确初始化的Logger对象:
use Psr\Log\LoggerInterface;
/**
* @Route("/mytest", name="default_mytest")
*/
public function MyTestLoggerAction(LoggerInterface $logger) {
dump($logger);
return $this->render('default/index.html.twig');
}
但是在Guards.php中名为Guards的自定义服务中,$ logger为空值:
namespace App\Workflow\CompanyDeploying\Transitions\Guards;
use Psr\Log\LoggerInterface;
class Guards {
private $logger;
public function setLogger(LoggerInterface $logger) {
$this->logger = $logger;
}
public function isValid() {
dump($this->logger);
}
}
我尝试过:
首次编辑
我的services.yaml
services:
# default configuration for services in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
public: false
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../src/*'
exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
# controllers are imported separately to make sure services can be injected
# as action arguments even if you don't extend any base controller class
App\Controller\:
resource: '../src/Controller'
tags: ['controller.service_arguments']
# add more service definitions when explicit configuration is needed
# please note that last definitions always *replace* previous ones
App\EventListener\CompanyIndexer:
tags:
- { name: doctrine.event_listener, event: prePersist }
我试图在services.yaml中强制自动装配,自动配置和可见性
App\Workflow\CompanyDeploying\Transitions\Guards\Guards:
autowire: true
autoconfigure: true
public: true
并添加我的Guards.php
private $logger;
/**
* @required
*/
public function setLogger(LoggerInterface $logger) {
$this->logger = $logger;
}
public function isValid() {
dump($this->logger);
}
但是没有成功。我总是转储一个空值。
第二次编辑
我从正在监听Wokflow事件的EventSubscriberInterface调用Guard服务:
public static function getSubscribedEvents()
{
return [
'workflow.company_deploying.enter.mystate' => 'onEnter',
'workflow.company_deploying.leave.mystate' => 'onLeave',
'workflow.company_deploying.guard.mystate' => 'guardMyTransition',
];
}
public function guardMyTransition(Event $event) {
$this->event = $event;
if (! $this->guardFactory(__FUNCTION__)->isValid()) {
$event->setBlocked(true);
}
}
protected function guardFactory($guardName) {
$guard = GuardsFactory::create($guardName);
$guard->setCompany($this->event->getSubject());
if (isset($this->entityManager)) $guard->setEntityManager($this->entityManager);
if (isset($this->previousState)) $guard->setPreviousState($this->previousState);
return $guard;
}
我的GuardFactory初始化Guards的子类。
在var / cache中,我有一个getGuardService.php
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
// This file has been auto-generated by the Symfony Dependency Injection Component for internal use.
// Returns the public 'App\Workflow\CompanyDeploying\Transitions\Guards\Guards' shared autowired service.
include_once $this->targetDirs[3].'/src/Workflow/CompanyDeploying/Transitions/Guards/Guards.php';
$this->services['App\\Workflow\\CompanyDeploying\\Transitions\\Guards\\Guards'] = $instance = new \App\Workflow\CompanyDeploying\Transitions\Guards\Guards();
$instance->setLogger(($this->privates['monolog.logger'] ?? $this->getMonolog_LoggerService()));
return $instance;
我只需要在我需要的每个类中轻松使用$ logger(或其他任何服务),而无需编写带有大量设置器的大量代码。
感谢您的帮助。
解决方案
依赖注入不适用于这种工厂调用。