@@ -815,20 +815,35 @@ Public Versus Private Services
815815From Symfony 4.0, every service defined is private by default.
816816
817817What does this mean? When a service **is ** public, you can access it directly
818- from the container object, which is accessible from any controller that extends
819- `` Controller `` ::
818+ from the container object, which can also be injected thanks to autowiring.
819+ This is mostly useful when you want to fetch services lazily ::
820820
821- use App\Service\MessageGenerator ;
821+ namespace App\Generator ;
822822
823- // ...
824- public function new()
823+ use Psr\Container\ContainerInterface;
824+
825+ class MessageGenerator
825826 {
826- // there IS a public "logger" service in the container
827- $logger = $this->container->get('logger');
827+ private $container;
828828
829- // this will NOT work: MessageGenerator is a private service
830- $generator = $this->container->get(MessageGenerator::class);
831- }
829+ public function __construct(ContainerInterface $container)
830+ {
831+ $this->container = $container;
832+ }
833+
834+ public function generate(string $message, string $template = null, array $context = []): string
835+ {
836+ if ($template && $this->container->has('twig')) {
837+ // there IS a public "twig" service in the container
838+ $twig = $this->container->get('twig');
839+
840+ return $twig->render($template, $context + ['message' => $message]);
841+ }
842+
843+ // if no template is passed, the "twig" service will not be loaded
844+
845+ // ...
846+ }
832847
833848As a best practice, you should only create *private * services, which will happen
834849automatically. And also, you should *not * use the ``$container->get() `` method to
@@ -845,7 +860,7 @@ But, if you *do* need to make a service public, override the ``public`` setting:
845860 # ... same code as before
846861
847862 # explicitly configure the service
848- App\Service\MessageGenerator :
863+ Acme\PublicService :
849864 public : true
850865
851866 .. code-block :: xml
@@ -861,7 +876,7 @@ But, if you *do* need to make a service public, override the ``public`` setting:
861876 <!-- ... same code as before -->
862877
863878 <!-- Explicitly configure the service -->
864- <service id =" App\Service\MessageGenerator " public =" true" ></service >
879+ <service id =" Acme\PublicService " public =" true" ></service >
865880 </services >
866881 </container >
867882
@@ -870,17 +885,22 @@ But, if you *do* need to make a service public, override the ``public`` setting:
870885 // config/services.php
871886 namespace Symfony\Component\DependencyInjection\Loader\Configurator;
872887
873- use App\Service\MessageGenerator ;
888+ use Acme\PublicService ;
874889
875890 return function(ContainerConfigurator $configurator) {
876891 // ... same as code before
877892
878893 // explicitly configure the service
879- $services->set(MessageGenerator ::class)
894+ $services->set(PublicService ::class)
880895 ->public()
881896 ;
882897 };
883898
899+ .. note ::
900+
901+ Instead of injecting the container you should consider using a
902+ :ref: `service locator <service-locators >` instead.
903+
884904.. _service-psr4-loader :
885905
886906Importing Many Services at once with resource
0 commit comments