Внедрение зависимостей Logger в пользовательский сервис - PullRequest
1 голос
/ 04 октября 2019

Я не могу понять, как работает 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 в Guards.php $ 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 всегда null.
  • добавление @required в getLogger () и установка public в true в services.yml, $ logger всегда null.
  • с использованием публичной функции isValid (LoggerInterface $ logger), но всего кодакто запрашивает этот метод isValid возвращает «Слишком мало аргументов для функции isValid ()»
  • с использованием __contruct (LoggerInterface $ logger), но везде, где мне нужен этот класс, код возвращает «Слишком мало аргументов для функции __construct () "

Первое редактирование

my 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 }

Я попытался принудительно включить автопровод, автоконфигурацию и видимость в сервисах. ямл

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);
}

но безуспешно. Я всегда сбрасываю нулевое значение.

2nd Edit

Я вызываю службу Guard из EventSubscriberInterface, который прослушивает событие Wokflow:

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 (или любой другойсервис) в каждом классе мне нужно без написания тонны кодов с большим количеством установщиков.

Спасибо за вашу помощь.

Решение

Внедрение зависимостине работает с таким заводским вызовом.

...