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:
_defaults:
autowire: true
autoconfigure: true
public: false
MyBundle\Controller\:
resource: '../../Controller/'
public: true
tags: ['controller.service_arguments']
MyBundle\A:
public:false
<?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();
}
}
<?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
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.
I agree it's a bit unclear behavior. Not all paths can be covered I guess.