jdog
jdog

Reputation: 2549

Symfony autowiring Event Listener

Symfony 4.2.2

To cache all responses in one controller, I'm using an event listener for the kernel.controller event. My Event listener needs a couple of services and info:

I have set this up like this:

namespace App\Listener;


use App\Controller\DataOutputController;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Debug\TraceableEventDispatcher;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;

class CachedOutput{

    protected $cacheFolder;
    protected $em;
    protected $controller;
    public function __construct($cacheFolder, EntityManagerInterface $em, DataOutputController $controller )
    {
        $this->cacheFolder = $cacheFolder;
        $this->em = $em;
        $this->controller = $controller;
    }



    public function findCachedObject(FilterControllerEvent $event, $eventName, TraceableEventDispatcher $dispatcher

    ){
        $params      = $event->getRequest()->attributes->get('_route_params');

        $fileType = $this->em->getRepository('App:FileType')->find($params->get('fileType'));
        $dataSet = $this->controller->getDataSet($params->get('dataSetSearch')?:'latest', $fileType->getType());

        $cacheFile = $this->cacheFolder.'/output/DS'.$dataSet->getId().'-FT'.$fileType->getId().'.html';

        if (file_exists($cacheFile)){
            $fh = fopen($cacheFile,'r');
            return new Response(fpassthru($fh));
        }
    }



}



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: true       # Allows optimizing the container by removing unused services; this also means
                            # fetching services directly from the container via $container->get() won't work.
                            # The best practice is to be explicit about your dependencies anyway.
        bind:
            $projectDir: '%kernel.project_dir%'
    # 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']


    controller.return_cached_output:
        class: App\Listener\CachedOutput
        arguments:
            $cacheFolder: "%kernel.cache_dir%"
        tags:
            - { name: kernel.event_listener, event: kernel.controller, method: findCachedObject }

However, I still get an error regarding the cache folder:

Cannot autowire service "App\Listener\CachedOutput": argument "$cacheFolder" of method "__construct()" has no type-hint, you should configure its value explicitly.

What am I missing?

Update:

Have tried to use alias for the service like this:

App\Listener\CachedOutput:
    public: false
    arguments:
        $cacheFolder: "%kernel.cache_dir%"
    tags:
        - { name: kernel.event_listener, event: kernel.controller, method: findCachedObject }

return_cached_output:
    alias: App\Listener\CachedOutput
    public: true

with no success

Upvotes: 1

Views: 2731

Answers (1)

Youssef Saoubou
Youssef Saoubou

Reputation: 591

You need to type-hint in your __construct(string $cacheFolder, ...)

Upvotes: 1

Related Questions