Movatterモバイル変換


[0]ホーム

URL:


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

Sign up
Appearance settings

Commit6c60e00

Browse files
committed
Service subscribers draft
1 parentd8fcd1c commit6c60e00

File tree

1 file changed

+175
-0
lines changed

1 file changed

+175
-0
lines changed
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
..index::
2+
single: DependencyInjection; Service Subscribers
3+
4+
Service Subscribers
5+
================
6+
7+
Symfony's Service Locators provide a powerful way of passing a subset of
8+
services from the service container to a service. Sometimes, you may want a
9+
more concrete way of defining the services contained within a service locator.
10+
By implementing ``ServiceSubscriberInterface`` you can specify the contents of
11+
the service locator from the object itself. This is useful when a set of
12+
services have the same parent class and similar dependencies.
13+
14+
Suppose you've got a mailing system with multiple ``Updater`` classes for
15+
sending out mails on different occasions. Since every updater has the same
16+
purpose, we start with a base updater::
17+
18+
// src/Updates/AbstractUpdater.php
19+
namespace App\Updates;
20+
21+
use Twig\Environment;
22+
23+
abstract class AbstractUpdater
24+
{
25+
protected $mailer;
26+
protected $twig;
27+
28+
public function __construct(\Swift_Mailer $mailer, Environment $twig)
29+
{
30+
$this->mailer = $mailer;
31+
$this->twig = $twig;
32+
}
33+
34+
abstract public function update($entity);
35+
36+
/**
37+
* Renders a view with Twig
38+
*/
39+
public function render($template, $parameters)
40+
{
41+
return $this->twig->render($template, $parameters);
42+
}
43+
44+
/**
45+
* Sends an email with Swiftmailer
46+
*/
47+
public function send($recipient, $title, $body)
48+
{
49+
$message = new \Swift_Message();
50+
51+
// ...
52+
53+
$this->mailer->send($message);
54+
}
55+
}
56+
57+
Now that we have a base class, we can add updaters for different entities. Note
58+
that we have to inject the dependencies of ``AbstractUpdater`` to each
59+
updater.::
60+
61+
// src/Updates/FooUpdater.php
62+
namespace App\Updates;
63+
64+
use Doctrine\Common\Persistence\ManagerRegistry;
65+
use Twig\Environment;
66+
67+
class FooUpdater extends AbstractUpdater
68+
{
69+
private $doctrine;
70+
71+
public function __construct(\Swift_Mailer $mailer, Environment $twig, ManagerRegistry $doctrine)
72+
{
73+
parent::__construct($mailer, $twig);
74+
75+
$this->doctrine = $doctrine;
76+
}
77+
78+
public function update($entity)
79+
{
80+
// ...
81+
82+
$body = $this->render('Emails/foo_update.html.twig', [/* ... */]);
83+
$this->send($entity->getRecipient(), 'Foo update', $body);
84+
}
85+
}
86+
87+
// src/Updates/BarUpdater.php
88+
namespace App\Updates;
89+
90+
use Doctrine\Common\Persistence\ManagerRegistry;
91+
use Twig\Environment;
92+
93+
class BarUpdater extends AbstractUpdater
94+
{
95+
private $doctrine;
96+
private $barManager;
97+
98+
public function __construct(\Swift_Mailer $mailer, Environment $twig, ManagerRegistry $doctrine, $barManager = null)
99+
{
100+
parent::__construct($mailer, $twig);
101+
102+
$this->doctrine = $doctrine;
103+
$this->barManager = $barManager;
104+
}
105+
106+
public function update($entity)
107+
{
108+
// ...
109+
110+
$body = $this->render('Emails/bar_update.html.twig', [/* ... */]);
111+
$this->send($entity->getRecipient(), 'Bar update', $body);
112+
}
113+
}
114+
115+
If you're using the `default services.yaml configuration`_, no additional
116+
configuration is required for these services thanks to autowiring, but
117+
maintaining the list of dependencies through constructor injection will quickly
118+
become cumbersome, especially if you add a dependency in ``AbstractUpdater``.
119+
120+
By creating a service subscriber of the base class, we can create a more
121+
practical solution for our dependencies.
122+
123+
Defining a Service Subscriber
124+
-----------------------------
125+
126+
First, turn ``AbstractUpdater`` into an implementation of
127+
``ServiceSubscriberInterface`` by adding the static method
128+
``getSubscribedServices`` which maintains a list of subscribed services and
129+
replacing our dependencies with a service locator.::
130+
131+
<code>
132+
133+
With this newly created service subscriber, the updaters can be adapted to
134+
coincide with the service locator::
135+
136+
<code>
137+
138+
Optionally, you'll need to add the ``container.service_subscriber`` tag to
139+
configure the services to be recognized as service subscribers.
140+
141+
..configuration-block::
142+
143+
..code-block::yaml
144+
145+
<code>
146+
147+
..code-block::xml
148+
149+
<code>
150+
151+
..code-block::php
152+
153+
<code>
154+
155+
Usage
156+
-----
157+
158+
Subscribed services
159+
-------------------
160+
161+
Returns an array of service types required by such instances, optionally keyed by the service names used internally.
162+
163+
For mandatory dependencies:
164+
165+
* array('logger' => 'Psr\Log\LoggerInterface') means the objects use the "logger" name
166+
internally to fetch a service which must implement Psr\Log\LoggerInterface.
167+
* array('Psr\Log\LoggerInterface') is a shortcut for
168+
* array('Psr\Log\LoggerInterface' => 'Psr\Log\LoggerInterface')
169+
170+
otherwise:
171+
172+
* array('logger' => '?Psr\Log\LoggerInterface') denotes an optional dependency
173+
* array('?Psr\Log\LoggerInterface') is a shortcut for
174+
* array('Psr\Log\LoggerInterface' => '?Psr\Log\LoggerInterface')
175+

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp