定制服务中Logger的依赖注入

时间:2019-10-04 08:31:30

标签: dependency-injection workflow symfony4 php-7.2

我无法理解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);
    }
}

我尝试过:

  • 使用LoggerAwareTrait,但没有其他反应,$ logger始终为空。
  • 在getLogger()上添加@required,并在services.yml中将public设置为true,$ logger始终为空。
  • 使用公共函数isValid(LoggerInterface $ logger),但是所有要求此isValid方法的代码都返回“函数isValid()的参数太少”
  • 使用__contruct(LoggerInterface $ logger),但在我需要此类的任何地方,代码返回“函数__construct()的参数太少”

首次编辑

我的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(或其他任何服务),而无需编写带有大量设置器的大量代码。

感谢您的帮助。

解决方案

依赖注入不适用于这种工厂调用。

0 个答案:

没有答案