Skip to content

Commit 23df135

Browse files
committed
minor #12885 [DependencyInjection] Reworded the article about factories (javiereguiluz)
This PR was merged into the 4.3 branch. Discussion ---------- [DependencyInjection] Reworded the article about factories This fixes #6029 by linking to an article which explains what factories are and by rewording contents a bit and introducing sections for a better navigation. Commits ------- 03956a8 [DependencyInjection] Reworded the article about factories
2 parents 160a212 + 03956a8 commit 23df135

File tree

1 file changed

+36
-22
lines changed

1 file changed

+36
-22
lines changed

service_container/factories.rst

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,17 @@
44
Using a Factory to Create Services
55
==================================
66

7-
Symfony's Service Container provides a powerful way of controlling the
8-
creation of objects, allowing you to specify arguments passed to the constructor
9-
as well as calling methods and setting parameters. Sometimes, however, this
10-
will not provide you with everything you need to construct your objects.
11-
For this situation, you can use a factory to create the object and tell
12-
the service container to call a method on the factory rather than directly
13-
instantiating the class.
7+
Symfony's Service Container provides multiple features to control the creation
8+
of objects, allowing you to specify arguments passed to the constructor as well
9+
as calling methods and setting parameters.
10+
11+
However, sometimes you need to apply the `factory design pattern`_ to delegate
12+
the object creation to some special object called "the factory". In those cases,
13+
the service container can call a method on your factory to create the object
14+
rather than directly instantiating the class.
15+
16+
Static Factories
17+
----------------
1418

1519
Suppose you have a factory that configures and returns a new ``NewsletterManager``
1620
object by calling the static ``createNewsletterManager()`` method::
@@ -27,9 +31,9 @@ object by calling the static ``createNewsletterManager()`` method::
2731
}
2832
}
2933

30-
To make the ``NewsletterManager`` object available as a service, you can
31-
configure the service container to use the
32-
``NewsletterManagerStaticFactory::createNewsletterManager()`` factory method:
34+
To make the ``NewsletterManager`` object available as a service, use the
35+
``factory`` option to define which method of which class must be called to
36+
create its object:
3337

3438
.. configuration-block::
3539

@@ -40,7 +44,7 @@ configure the service container to use the
4044
# ...
4145
4246
App\Email\NewsletterManager:
43-
# call the static method
47+
# the first argument is the class and the second argument is the static method
4448
factory: ['App\Email\NewsletterManagerStaticFactory', 'createNewsletterManager']
4549
4650
.. code-block:: xml
@@ -54,7 +58,7 @@ configure the service container to use the
5458
5559
<services>
5660
<service id="App\Email\NewsletterManager">
57-
<!-- call the static method -->
61+
<!-- the first argument is the class and the second argument is the static method -->
5862
<factory class="App\Email\NewsletterManagerStaticFactory" method="createNewsletterManager"/>
5963
6064
<!-- if the factory class is the same as the service class, you can omit
@@ -77,8 +81,8 @@ configure the service container to use the
7781
return function(ContainerConfigurator $configurator) {
7882
$services = $configurator->services();
7983
80-
// call the static method
8184
$services->set(NewsletterManager::class)
85+
// the first argument is the class and the second argument is the static method
8286
->factory([NewsletterManagerStaticFactory::class, 'createNewsletterManager']);
8387
};
8488
@@ -91,11 +95,11 @@ configure the service container to use the
9195
the configured class name may be used by compiler passes and therefore
9296
should be set to a sensible value.
9397

94-
If your factory is not using a static function to configure and create your
95-
service, but a regular method, you can instantiate the factory itself as a
96-
service too. Later, in the ":ref:`factories-passing-arguments-factory-method`"
97-
section, you learn how you can inject arguments in this method.
98+
Non-Static Factories
99+
--------------------
98100

101+
If your factory is using a regular method instead of a static one to configure
102+
and create the service, instantiate the factory itself as a service too.
99103
Configuration of the service container then looks like this:
100104

101105
.. configuration-block::
@@ -106,10 +110,12 @@ Configuration of the service container then looks like this:
106110
services:
107111
# ...
108112
113+
# first, create a service for the factory
109114
App\Email\NewsletterManagerFactory: ~
110115
116+
# second, use the factory service as the first argument of the 'factory'
117+
# option and the factory method as the second argument
111118
App\Email\NewsletterManager:
112-
# call a method on the specified factory service
113119
factory: ['@App\Email\NewsletterManagerFactory', 'createNewsletterManager']
114120
115121
.. code-block:: xml
@@ -122,10 +128,12 @@ Configuration of the service container then looks like this:
122128
https://symfony.com/schema/dic/services/services-1.0.xsd">
123129
124130
<services>
131+
<!-- first, create a service for the factory -->
125132
<service id="App\Email\NewsletterManagerFactory"/>
126133
134+
<!-- second, use the factory service as the first argument of the 'factory'
135+
option and the factory method as the second argument -->
127136
<service id="App\Email\NewsletterManager">
128-
<!-- call a method on the specified factory service -->
129137
<factory service="App\Email\NewsletterManagerFactory"
130138
method="createNewsletterManager"
131139
/>
@@ -144,15 +152,20 @@ Configuration of the service container then looks like this:
144152
return function(ContainerConfigurator $configurator) {
145153
$services = $configurator->services();
146154
155+
// first, create a service for the factory
147156
$services->set(NewsletterManagerFactory::class);
148157
149-
// call a method on the specified factory service
158+
// second, use the factory service as the first argument of the 'factory'
159+
// method and the factory method as the second argument
150160
$services->set(NewsletterManager::class)
151161
->factory([ref(NewsletterManagerFactory::class), 'createNewsletterManager']);
152162
};
153163
154164
.. _factories-invokable:
155165

166+
Invokable Factories
167+
-------------------
168+
156169
Suppose you now change your factory method to ``__invoke()`` so that your
157170
factory service can be used as a callback::
158171

@@ -234,8 +247,8 @@ Passing Arguments to the Factory Method
234247
that's enabled for your service.
235248

236249
If you need to pass arguments to the factory method you can use the ``arguments``
237-
options. For example, suppose the ``createNewsletterManager()`` method in the previous
238-
example takes the ``templating`` service as an argument:
250+
option. For example, suppose the ``createNewsletterManager()`` method in the
251+
previous examples takes the ``templating`` service as an argument:
239252

240253
.. configuration-block::
241254

@@ -285,3 +298,4 @@ example takes the ``templating`` service as an argument:
285298
;
286299
};
287300
301+
.. _`factory design pattern`: https://en.wikipedia.org/wiki/Factory_(object-oriented_programming)

0 commit comments

Comments
 (0)