Friedrich Roell
Friedrich Roell

Reputation: 457

symfony v3.3.6 unexpected service behaviour

Im working on a Symfony3 project and playing around with the "new" dependency injection mechanism. can some please explain the following behavior to me please:

this is my setup:


services.yml

services:
  _defaults:
    autowire: true
    autoconfigure: true
    public: false

  MyBundle\Controller\:
    resource: '../../Controller/'
    public: true
    tags: ['controller.service_arguments']

  MyBundle\A: 
    public:false

Controller Scenario A

<?php

namespace MyBundle\Controller;

use ...

class RootController extends Controller
{
    /**
     * @Route("/", name="root")
     */
    public function indexAction(A $a) <- INJECTION HERE
    {
        $b = $this->get(A::class); // NO EXCEPTION THROWN HERE

        return new Response(); 
    }
}

Controller Scenario B

<?php

namespace MyBundle\Controller;

use ...

class RootController extends Controller
{
    /**
     * @Route("/", name="root")
     */
    public function indexAction() // <- NO INJECTION
    {
        $b = $this->get(A::class); // EXCEPTION THROWN HERE

        return new Response(); 
    }
}

Im trying to fetch service A inside the indexAction from the container. As I marked it private in my services.yml I'm expecting an Exception when trying to grab it (like in Scenario B). But in Scenario A I'm not getting an Exception because the service A has already been injected (auto wired) into the Controller.

(here the (expected) Exception of Scenario B: You have requested a non-existent service "MyBundle\A".)

Can some explain this behaviour please.

cheers

Upvotes: 1

Views: 115

Answers (2)

Tomas Votruba
Tomas Votruba

Reputation: 24280

After bit of explaining in the comments I understand your question as:

How does a private service becomes public by request in the controller action?

With action injection these services collected are re-registred with ServiceLocator class, which make it accessible with ->get().

See RegisterControllerArgumentLocatorsPass here.

enter image description here

I agree it's a bit unclear behavior. Not all paths can be covered I guess.

Upvotes: 1

JerzySBG
JerzySBG

Reputation: 109

Invalid behavior of private services is described here: http://symfony.com/blog/new-in-symfony-3-2-improved-private-services

Requesting a private service with the Container::get() method is deprecated in Symfony 3.2 and no longer returns the service in 4.0.

Does it log any 'deprecated' in developers log?

Upvotes: 0

Related Questions