Home > Mobile >  symfony5 service - how to inject session and user without the ContainerInterface
symfony5 service - how to inject session and user without the ContainerInterface

Time:08-28

I have this deprecation message:

Since symfony/dependency-injection 5.1: The "Symfony\Component\DependencyInjection\ContainerInterface" autowiring alias is deprecated. Define it explicitly in your app if you want to keep using it.

From threads such as this Symfony: Explicit define Container in Service I understand that the long-term solution is to stop using the ContainerInterface all together in my services.

My services.yaml looks like this:

parameters:
    #locale: en
    basepath: '%env(basepath)%'

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.

    # 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/'
            - '../src/Entity/'
            - '../src/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
    globalHelper:
        class: App\Service\globalHelper
        public: false

The service in question (globalHelper) looks like this:

<?php
namespace App\Service;

use Symfony\Component\DependencyInjection\ContainerInterface as Container;
use Doctrine\ORM\EntityManagerInterface as EntityManager;

class globalHelper {

    private $container;
    private $em;

    public function __construct(Container $container, EntityManager $em) {
        $this->container = $container;
        $this->em = $em;
    }

I only user the container to fetch session variables like this

$this->container->get('session')->getFlashBag()->add($type, $message);

And to get the current user (security context) like this

$this->container->get('security.context')->getToken()->getUser();

Can I get these sub-components of the container separately instead? What component then would I inject to access these two parts (session and user) respectively?

--------------- Addition --------------

According to Alexis' suggestion below I modified the head of the file with

<?php
namespace App\Service;

//use Symfony\Component\DependencyInjection\ContainerInterface as Container;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Security\Core\Security;
use Doctrine\ORM\EntityManagerInterface as EntityManager;

class globalHelper {

    //private $container;
    private $requestStack;
    private $security;
    private $em;

    //public function __construct(Container $container, RequestStack $requestStack, Security $security, EntityManager $em) {
    public function __construct(RequestStack $requestStack, Security $security, EntityManager $em) {
        //$this->container = $container;
        $this->requestStack = $requestStack;
        $this->security = $security;
        $this->em = $em;
    }

then replaced

$this->container->get('session')->getFlashBag()->add($type, $message);

with

$this->requestStack->getSession()->getFlashBag()->add($type, $message);

and get this error:

Attempted to call an undefined method named "getSession" of class "Symfony\Component\HttpFoundation\RequestStack".

if I instead to this:

$this->requestStack->get('session')->getFlashBag()->add($type, $message);

Attempted to call an undefined method named "get" of class "Symfony\Component\HttpFoundation\RequestStack". Did you mean to call e.g. "getCurrentRequest", "getMasterRequest" or "getParentRequest"?

CodePudding user response:

First it’s not mandatory to declare your service help with

autoconfigure: true

Then you must inject

Symfony\Component\HttpFoundation\RequestStack

and make

$requestStack->getSession()

Here's the docs

https://symfony.com/doc/current/session.html

For user you inject

Symfony\Component\Security\Core\Security

and make

$security->getUser()

Here's the docs

https://symfony.com/doc/current/security.html#fetching-the-user-from-a-service

-- EDIT --

Prio symfony 5.3 session can directly be injected with

Symfony\Component\HttpFoundation\Session\SessionInterface

It's depreciated after. Here's the blog post :

https://symfony.com/blog/new-in-symfony-5-3-session-service-deprecation

  • Related