Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 7838a50

Browse filesBrowse files
committed
Merge branch '6.2' into 6.3
* 6.2: Improve description of ad hoc containers
2 parents a9cbfe9 + e3cfa6d commit 7838a50
Copy full SHA for 7838a50

File tree

1 file changed

+45
-53
lines changed
Filter options

1 file changed

+45
-53
lines changed

‎service_container/service_subscribers_locators.rst

Copy file name to clipboardExpand all lines: service_container/service_subscribers_locators.rst
+45-53Lines changed: 45 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -30,24 +30,22 @@ to handle their respective command when it is asked for::
3030
class CommandBus
3131
{
3232
/**
33-
* @var CommandHandler[]
33+
* @param CommandHandler[] $handlerMap
3434
*/
35-
private $handlerMap;
36-
37-
public function __construct(array $handlerMap)
38-
{
39-
$this->handlerMap = $handlerMap;
35+
public function __construct(
36+
private array $handlerMap,
37+
) {
4038
}
4139

4240
public function handle(Command $command)
4341
{
4442
$commandClass = get_class($command);
4543

46-
if (!isset($this->handlerMap[$commandClass])) {
44+
if (!$handler = $this->handlerMap[$commandClass] ?? null) {
4745
return;
4846
}
4947

50-
return $this->handlerMap[$commandClass]->handle($command);
48+
return $handler->handle($command);
5149
}
5250
}
5351

@@ -72,8 +70,7 @@ Defining a Service Subscriber
7270

7371
First, turn ``CommandBus`` into an implementation of :class:`Symfony\\Contracts\\Service\\ServiceSubscriberInterface`.
7472
Use its ``getSubscribedServices()`` method to include as many services as needed
75-
in the service subscriber and change the type hint of the container to
76-
a PSR-11 ``ContainerInterface``::
73+
in the service subscriber::
7774

7875
// src/CommandBus.php
7976
namespace App;
@@ -85,11 +82,9 @@ a PSR-11 ``ContainerInterface``::
8582

8683
class CommandBus implements ServiceSubscriberInterface
8784
{
88-
private $locator;
89-
90-
public function __construct(ContainerInterface $locator)
91-
{
92-
$this->locator = $locator;
85+
public function __construct(
86+
private ContainerInterface $locator,
87+
) {
9388
}
9489

9590
public static function getSubscribedServices(): array
@@ -119,8 +114,12 @@ a PSR-11 ``ContainerInterface``::
119114
can also manually add the ``container.service_subscriber`` tag.
120115

121116
The injected service is an instance of :class:`Symfony\\Component\\DependencyInjection\\ServiceLocator`
122-
which implements the PSR-11 ``ContainerInterface``, but it is also a callable::
117+
which implements both the PSR-11 ``ContainerInterface`` and :class:`Symfony\\Contracts\\Service\\ServiceProviderInterface`.
118+
It is also a callable and a countable::
123119

120+
// ...
121+
$numberOfHandlers = count($this->locator);
122+
$nameOfHandlers = array_keys($this->locator->getProvidedServices());
124123
// ...
125124
$handler = ($this->locator)($commandClass);
126125

@@ -312,15 +311,16 @@ argument of type ``service_locator``.
312311
Consider the following ``CommandBus`` class where you want to inject
313312
some services into it via a service locator::
314313

315-
// src/HandlerCollection.php
314+
// src/CommandBus.php
316315
namespace App;
317316

318-
use Symfony\Component\DependencyInjection\ServiceLocator;
317+
use Psr\Container\ContainerInterface;
319318

320319
class CommandBus
321320
{
322-
public function __construct(ServiceLocator $locator)
323-
{
321+
public function __construct(
322+
private ContainerInterface $locator,
323+
) {
324324
}
325325
}
326326

@@ -334,14 +334,15 @@ or directly via PHP attributes:
334334
// src/CommandBus.php
335335
namespace App;
336336
337+
use Psr\Container\ContainerInterface;
337338
use Symfony\Component\DependencyInjection\Attribute\TaggedLocator;
338-
use Symfony\Component\DependencyInjection\ServiceLocator;
339339
340340
class CommandBus
341341
{
342342
public function __construct(
343343
// creates a service locator with all the services tagged with 'app.handler'
344-
#[TaggedLocator('app.handler')] ServiceLocator $locator
344+
#[TaggedLocator('app.handler')]
345+
private ContainerInterface $locator,
345346
) {
346347
}
347348
}
@@ -571,14 +572,14 @@ of the ``key`` tag attribute (as defined in the ``index_by`` locator option):
571572
// src/CommandBus.php
572573
namespace App;
573574
575+
use Psr\Container\ContainerInterface;
574576
use Symfony\Component\DependencyInjection\Attribute\TaggedLocator;
575-
use Symfony\Component\DependencyInjection\ServiceLocator;
576577
577578
class CommandBus
578579
{
579580
public function __construct(
580581
#[TaggedLocator('app.handler', indexAttribute: 'key')]
581-
ServiceLocator $locator
582+
private ContainerInterface $locator,
582583
) {
583584
}
584585
}
@@ -652,13 +653,13 @@ Inside this locator you can retrieve services by index using the value of the
652653
// src/Handler/HandlerCollection.php
653654
namespace App\Handler;
654655

655-
use Symfony\Component\DependencyInjection\ServiceLocator;
656+
use Psr\Container\ContainerInterface;
656657

657658
class HandlerCollection
658659
{
659-
public function __construct(ServiceLocator $locator)
660+
public function getHandlerTwo(ContainerInterface $locator)
660661
{
661-
$handlerTwo = $locator->get('handler_two');
662+
return $locator->get('handler_two');
662663
}
663664

664665
// ...
@@ -691,14 +692,14 @@ attribute to the locator service defining the name of this custom method:
691692
// src/CommandBus.php
692693
namespace App;
693694
695+
use Psr\Container\ContainerInterface;
694696
use Symfony\Component\DependencyInjection\Attribute\TaggedLocator;
695-
use Symfony\Component\DependencyInjection\ServiceLocator;
696697
697698
class CommandBus
698699
{
699700
public function __construct(
700701
#[TaggedLocator('app.handler', 'key', defaultIndexMethod: 'myOwnMethodName')]
701-
ServiceLocator $locator
702+
private ContainerInterface $locator,
702703
) {
703704
}
704705
}
@@ -758,7 +759,7 @@ The :class:`Symfony\\Contracts\\Service\\ServiceSubscriberTrait` provides an
758759
implementation for :class:`Symfony\\Contracts\\Service\\ServiceSubscriberInterface`
759760
that looks through all methods in your class that are marked with the
760761
:class:`Symfony\\Contracts\\Service\\Attribute\\SubscribedService` attribute. It
761-
provides a ``ServiceLocator`` for the services of each method's return type.
762+
describes the services needed by the class based on each method's return type.
762763
The service id is ``__METHOD__``. This allows you to add dependencies to your
763764
services based on type-hinted helper methods::
764765

@@ -916,34 +917,25 @@ Here's an example::
916917
Testing a Service Subscriber
917918
----------------------------
918919

919-
To unit test a service subscriber, you can create a fake ``ServiceLocator``::
920+
To unit test a service subscriber, you can create a fake container::
920921

921-
use Symfony\Component\DependencyInjection\ServiceLocator;
922+
use Symfony\Contracts\Service\ServiceLocatorTrait;
923+
use Symfony\Contracts\Service\ServiceProviderInterface;
922924

923-
$container = new class() extends ServiceLocator {
924-
private $services = [];
925+
// Create the fake services
926+
$foo = new stdClass();
927+
$bar = new stdClass();
928+
$bar->foo = $foo;
925929

926-
public function __construct()
927-
{
928-
parent::__construct([
929-
'foo' => function () {
930-
return $this->services['foo'] = $this->services['foo'] ?? new stdClass();
931-
},
932-
'bar' => function () {
933-
return $this->services['bar'] = $this->services['bar'] ?? $this->createBar();
934-
},
935-
]);
936-
}
937-
938-
private function createBar()
939-
{
940-
$bar = new stdClass();
941-
$bar->foo = $this->get('foo');
942-
943-
return $bar;
944-
}
930+
// Create the fake container
931+
$container = new class([
932+
'foo' => fn () => $foo,
933+
'bar' => fn () => $bar,
934+
]) implements ServiceProviderInterface {
935+
use ServiceLocatorTrait;
945936
};
946937

938+
// Create the service subscriber
947939
$serviceSubscriber = new MyService($container);
948940
// ...
949941

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.