Symfony version(s) affected: 5.0.1
PHP Version: 7.4.0
Description
According to the Service Container documentation about public vs private services, I cannot reproduce a public accessible service via $container->get().
Even if I follow the How to Create Service Aliases and Mark Services as Private, with an alias, the service still behaves as _private_.
How to reproduce
The services configuration file:
# config/services.yaml
services:
# ...
App\Service\MessageGenerator:
public: true
The controller file:
use App\Service\MessageGenerator;
// ...
public funciton new()
{
$message = $this->container->get(MessageGenerator::class);
}
The error:

i figure you're accessing the service locator from AbstractController ..., which is a smaller subset of the full container :) AFAIK you should inject the full container @service_container / ContainerInterface $container as needed. Do the docs tell otherwise?
the DI/service container docs dont assume AbstractController, so this is confusing .. but technically correct :)
for controllers (https://symfony.com/doc/current/controller.html) we dont mention accessing the service locator even.. so it seems 2 concepts are combined, but im not sure how to handle it in the docs ;)
@ro0NL I couldn't find this _full container_ injection at the docs. Just following the documentations I cited, I'm unable to reproduce a public service.
I think we need an upgrade at the docs, or this is a bug. 馃槙
This is a documentation issue IMO. The issue in your case is that $this->container in an AbstractController is not the DIC Container (and that's on purpose). So $container in the doc you are reading is not the same than $this->container in the code you write.
In older Symfony versions, controllers were based on the (now removed) Controller abstract class, which contained a reference to the full DI Container object. So the confusion was not present. In modern Symfony versions, accessing the DI container instance is much less common.
@stof @ro0NL Thanks for the explanations guys! Now I know the differences about DI in Symfony 4 and Symfony 5.
The documentation is really out of date for version 5.* and beyond.
Well, the documentation of the DI components talks about a $container variable. AFAIK, it never tells you that this is the same that $this->container in your controller.
IMHO we should remove the "controller" example in https://symfony.com/doc/current/service_container.html#public-versus-private-services, in favor of a global runtime.
The example uses $this->container (controller-like), but the next line mentions $container->get() (global runtime)
Please open a doc issue. CLosing as there is nothing to keep track of on the code side. Thanks for submitting.
@nicolas-grekas perhaps transfer the issue to the doc repo instead :)
Transfering the issue makes sense. @xabbuh can you please do this?
Edit:
Oh already done 馃檭
I'm closing this as "fixed", because the mentioned article was updated in https://github.com/symfony/symfony-docs/pull/13486/files and we removed some confusing docs about injecting the entire container. Thanks.
Most helpful comment
This is a documentation issue IMO. The issue in your case is that
$this->containerin an AbstractController is not the DIC Container (and that's on purpose). So$containerin the doc you are reading is not the same than$this->containerin the code you write.In older Symfony versions, controllers were based on the (now removed) Controller abstract class, which contained a reference to the full DI Container object. So the confusion was not present. In modern Symfony versions, accessing the DI container instance is much less common.