Skip to content

Commit e27d27b

Browse files
committed
[DependencyInjection] Fluent PHP DI Documentation
- Updated DI configuration references to include php-fluent-di - Updated _build/conf.py to include codeblock for php-fluent-di - Updated existing di resource loading to refer to latest sf 4.2 excludes Signed-off-by: RJ Garcia <rj@bighead.net>
1 parent 4d0bafa commit e27d27b

19 files changed

+616
-359
lines changed

components/dependency_injection.rst

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -288,17 +288,21 @@ config files:
288288
289289
.. code-block:: php
290290
291-
use Symfony\Component\DependencyInjection\Reference;
291+
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
292+
293+
return function(ContainerConfigurator $configurator) {
294+
$configurator->parameters()
295+
->set('mailer.transport', 'sendmail');
296+
297+
$container = $configurator->services();
298+
299+
$container->set('mailer', 'Mailer')
300+
->args(['%mailer.transport%']);
301+
302+
$container->set('newsletter_manager', 'NewsletterManager')
303+
->call('setMailer', [ref('mailer')]);
304+
};
292305
293-
// ...
294-
$container->setParameter('mailer.transport', 'sendmail');
295-
$container
296-
->register('mailer', 'Mailer')
297-
->addArgument('%mailer.transport%');
298-
299-
$container
300-
->register('newsletter_manager', 'NewsletterManager')
301-
->addMethodCall('setMailer', [new Reference('mailer')]);
302306
303307
Learn More
304308
----------

service_container.rst

Lines changed: 96 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -182,19 +182,18 @@ each time you ask for it.
182182
.. code-block:: php
183183
184184
// config/services.php
185-
use Symfony\Component\DependencyInjection\Definition;
185+
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
186186
187-
// To use as default template
188-
$definition = new Definition();
187+
return function(ContainerConfigurator $configurator) {
188+
$container = $configurator->services()
189+
->defaults()
190+
->autowire()
191+
->autoconfigure()
192+
->private();
189193
190-
$definition
191-
->setAutowired(true)
192-
->setAutoconfigured(true)
193-
->setPublic(false)
194-
;
195-
196-
// $this is a reference to the current loader
197-
$this->registerClasses($definition, 'App\\', '../src/*', '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}');
194+
$container->load('App\\', '../src/*')
195+
->exclude('../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}');
196+
};
198197
199198
.. tip::
200199

@@ -396,7 +395,7 @@ pass here. No problem! In your configuration, you can explicitly set this argume
396395
# same as before
397396
App\:
398397
resource: '../src/*'
399-
exclude: '../src/{Entity,Migrations,Tests}'
398+
exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
400399
401400
# explicitly configure the service
402401
App\Updates\SiteUpdateManager:
@@ -416,6 +415,7 @@ pass here. No problem! In your configuration, you can explicitly set this argume
416415
<!-- ... -->
417416
418417
<!-- Same as before -->
418+
419419
<prototype namespace="App\" resource="../src/*" exclude="../src/{Entity,Migrations,Tests}"/>
420420
421421
<!-- Explicitly configure the service -->
@@ -428,23 +428,23 @@ pass here. No problem! In your configuration, you can explicitly set this argume
428428
.. code-block:: php
429429
430430
// config/services.php
431+
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
432+
431433
use App\Updates\SiteUpdateManager;
432-
use Symfony\Component\DependencyInjection\Definition;
433434
434-
// Same as before
435-
$definition = new Definition();
435+
return function(ContainerConfigurator $configurator) {
436+
$container = $configurator->services()
437+
->defaults()
438+
->autowire()
439+
->autoconfigure()
440+
->private();
436441
437-
$definition
438-
->setAutowired(true)
439-
->setAutoconfigured(true)
440-
->setPublic(false)
441-
;
442+
$container->load('App\\', '../src/*')
443+
->exclude('../src/{Entity,Migrations,Tests}');
442444
443-
$this->registerClasses($definition, 'App\\', '../src/*', '../src/{Entity,Migrations,Tests}');
445+
$container->set(SiteUpdateManager::class)->arg('$adminEmail', 'manager@example.com');
446+
};
444447
445-
// Explicitly configure the service
446-
$container->getDefinition(SiteUpdateManager::class)
447-
->setArgument('$adminEmail', 'manager@example.com');
448448
449449
Thanks to this, the container will pass ``manager@example.com`` to the ``$adminEmail``
450450
argument of ``__construct`` when creating the ``SiteUpdateManager`` service. The
@@ -503,13 +503,16 @@ parameter and in PHP config use the ``Reference`` class:
503503
.. code-block:: php
504504
505505
// config/services.php
506+
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
507+
506508
use App\Service\MessageGenerator;
507-
use Symfony\Component\DependencyInjection\Reference;
508509
509-
$container->autowire(MessageGenerator::class)
510-
->setAutoconfigured(true)
511-
->setPublic(false)
512-
->setArgument(0, new Reference('logger'));
510+
return function(ContainerConfigurator $configurator) {
511+
$container = $configurator->services();
512+
$container->set(MessageGenerator::class)
513+
->autoconfigure()
514+
->args([ref('logger')]]);
515+
};
513516
514517
Working with container parameters is straightforward using the container's
515518
accessor methods for parameters::
@@ -605,13 +608,18 @@ But, you can control this and pass in a different logger:
605608
.. code-block:: php
606609
607610
// config/services.php
611+
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
612+
608613
use App\Service\MessageGenerator;
609-
use Symfony\Component\DependencyInjection\Reference;
610614
611-
$container->autowire(MessageGenerator::class)
612-
->setAutoconfigured(true)
613-
->setPublic(false)
614-
->setArgument('$logger', new Reference('monolog.logger.request'));
615+
return function(ContainerConfigurator $configurator) {
616+
$container = $configurator->services();
617+
$container->set(SiteUpdateManager::class)
618+
->autowire()
619+
->autoconfigure()
620+
->private();
621+
->arg('$logger', ref('monolog.logger.request'));
622+
};
615623
616624
This tells the container that the ``$logger`` argument to ``__construct`` should use
617625
service whose id is ``monolog.logger.request``.
@@ -693,21 +701,22 @@ You can also use the ``bind`` keyword to bind specific arguments by name or type
693701
.. code-block:: php
694702
695703
// config/services.php
704+
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
705+
696706
use App\Controller\LuckyController;
697707
use Psr\Log\LoggerInterface;
698708
use Symfony\Component\DependencyInjection\Reference;
699709
700-
$container->register(LuckyController::class)
701-
->setPublic(true)
702-
->setBindings([
703-
'$adminEmail' => 'manager@example.com',
704-
'$requestLogger' => new Reference('monolog.logger.request'),
705-
LoggerInterface::class => new Reference('monolog.logger.request'),
706-
// optionally you can define both the name and type of the argument to match
707-
'string $adminEmail' => 'manager@example.com',
708-
LoggerInterface::class.' $requestLogger' => new Reference('monolog.logger.request'),
709-
])
710-
;
710+
return function(ContainerConfigurator $configurator) {
711+
$container = $configurator->services()->defaults()
712+
->bind('$adminEmail', 'manager@example.com')
713+
->bind('$requestLogger', ref('monolog.logger.request'))
714+
->bind(LoggerInterface::class, ref('monolog.logger.request'))
715+
->bind('string $adminEmail', 'manager@example.com')
716+
->bind(LoggerInterface::class.' $requestLogger', ref('monolog.logger.request'));
717+
718+
// ...
719+
};
711720
712721
By putting the ``bind`` key under ``_defaults``, you can specify the value of *any*
713722
argument for *any* service defined in this file! You can bind arguments by name
@@ -809,6 +818,20 @@ But, if you *do* need to make a service public, override the ``public`` setting:
809818
</services>
810819
</container>
811820
821+
.. code-block:: php
822+
823+
// config/services.php
824+
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
825+
826+
use App\Service\MessageGenerator;
827+
828+
return function(ContainerConfigurator $configurator) {
829+
// ... same as code before
830+
831+
$container->set(MessageGenerator::class)
832+
->public();
833+
};
834+
812835
.. _service-psr4-loader:
813836

814837
Importing Many Services at once with resource
@@ -829,7 +852,7 @@ key. For example, the default Symfony configuration contains this:
829852
# this creates a service per class whose id is the fully-qualified class name
830853
App\:
831854
resource: '../src/*'
832-
exclude: '../src/{Entity,Migrations,Tests}'
855+
exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
833856
834857
.. code-block:: xml
835858
@@ -850,18 +873,14 @@ key. For example, the default Symfony configuration contains this:
850873
.. code-block:: php
851874
852875
// config/services.php
853-
use Symfony\Component\DependencyInjection\Definition;
876+
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
854877
855-
// To use as default template
856-
$definition = new Definition();
857-
858-
$definition
859-
->setAutowired(true)
860-
->setAutoconfigured(true)
861-
->setPublic(false)
862-
;
878+
return function(ContainerConfigurator $configurator) {
879+
// ...
863880
864-
$this->registerClasses($definition, 'App\\', '../src/*', '../src/{Entity,Migrations,Tests}');
881+
$container->load('App\\', '../src/*')
882+
->exclude('../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}');
883+
};
865884
866885
.. tip::
867886

@@ -998,27 +1017,30 @@ admin email. In this case, each needs to have a unique service id:
9981017
.. code-block:: php
9991018
10001019
// config/services.php
1020+
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
1021+
10011022
use App\Service\MessageGenerator;
10021023
use App\Updates\SiteUpdateManager;
1003-
use Symfony\Component\DependencyInjection\Reference;
10041024
1005-
$container->register('site_update_manager.superadmin', SiteUpdateManager::class)
1006-
->setAutowired(false)
1007-
->setArguments([
1008-
new Reference(MessageGenerator::class),
1009-
new Reference('mailer'),
1010-
'superadmin@example.com'
1011-
]);
1012-
1013-
$container->register('site_update_manager.normal_users', SiteUpdateManager::class)
1014-
->setAutowired(false)
1015-
->setArguments([
1016-
new Reference(MessageGenerator::class),
1017-
new Reference('mailer'),
1018-
'contact@example.com'
1019-
]);
1020-
1021-
$container->setAlias(SiteUpdateManager::class, 'site_update_manager.superadmin')
1025+
return function(ContainerConfigurator $configurator) {
1026+
// ...
1027+
1028+
$container->set('site_update_manager.superadmin', SiteUpdateManager::class)
1029+
->autowire(false)
1030+
->args([
1031+
ref(MessageGenerator::class),
1032+
ref('mailer'),
1033+
'superadmin@example.com'
1034+
]);
1035+
$container->set('site_update_manager.normal_users', SiteUpdateManager::class)
1036+
->autowire(false)
1037+
->args([
1038+
ref(MessageGenerator::class),
1039+
ref('mailer'),
1040+
'contact@example.com'
1041+
]);
1042+
$container->alias(SiteUpdateManager::class, 'site_update_manager.superadmin');
1043+
};
10221044
10231045
In this case, *two* services are registered: ``site_update_manager.superadmin``
10241046
and ``site_update_manager.normal_users``. Thanks to the alias, if you type-hint

service_container/3.3-di-changes.rst

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,32 @@ what the file looks like in Symfony 4):
8181
</services>
8282
</container>
8383
84+
.. code-block:: php
85+
86+
// config/services.php
87+
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
88+
89+
return function(ContainerConfigurator $configurator) {
90+
$container = $configurator->services()
91+
->defaults()
92+
->autowire()
93+
->autoconfigure()
94+
->private();
95+
96+
$container->load('App\\', '../src/*')
97+
->exclude('../src/{Entity,Migrations,Tests}');
98+
99+
$container->load('App\\Controller\\', '../src/Controller')
100+
->tag('controller.service_arguments');
101+
};
102+
84103
This small bit of configuration contains a paradigm shift of how services
85104
are configured in Symfony.
86105

106+
.. versionadded:: 3.4
107+
108+
PHP Fluent DI was introduced in Symfony 3.4.
109+
87110
.. _`service-33-changes-automatic-registration`:
88111

89112
1) Services are Loaded Automatically
@@ -126,6 +149,18 @@ thanks to the following config:
126149
</services>
127150
</container>
128151
152+
.. code-block:: php
153+
154+
// config/services.php
155+
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
156+
157+
return function(ContainerConfigurator $configurator) {
158+
// ...
159+
160+
$container->load('App\\', '../src/*')
161+
->exclude('../src/{Entity,Migrations,Tests}');
162+
};
163+
129164
This means that every class in ``src/`` is *available* to be used as a
130165
service. And thanks to the ``_defaults`` section at the top of the file, all of
131166
these services are **autowired** and **private** (i.e. ``public: false``).
@@ -319,11 +354,15 @@ The third big change is that, in a new Symfony 3.3 project, your controllers are
319354
.. code-block:: php
320355
321356
// config/services.php
357+
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
322358
323-
// ...
359+
return function(ContainerConfigurator $configurator) {
360+
// ...
361+
362+
$container->load('App\\Controller\\', '../src/Controller')
363+
->tag('controller.service_arguments');
364+
};
324365
325-
$definition->addTag('controller.service_arguments');
326-
$this->registerClasses($definition, 'App\\Controller\\', '../src/Controller/*');
327366
328367
But, you might not even notice this. First, your controllers *can* still extend
329368
the same base controller class (``AbstractController``).
@@ -464,6 +503,21 @@ inherited from an abstract definition:
464503
</services>
465504
</container>
466505
506+
.. code-block:: php
507+
508+
// config/services.php
509+
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
510+
511+
use App\Domain\LoaderInterface;
512+
513+
return function(ContainerConfigurator $configurator) {
514+
// ...
515+
516+
$container->instanceof(LoaderInterface::class
517+
->public()
518+
->tag('app.domain_loader');
519+
};
520+
467521
What about Performance
468522
----------------------
469523

0 commit comments

Comments
 (0)