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 23df135

Browse filesBrowse files
committed
minor symfony#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 symfony#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
Copy full SHA for 23df135

File tree

Expand file treeCollapse file tree

1 file changed

+36
-22
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+36
-22
lines changed

‎service_container/factories.rst

Copy file name to clipboardExpand all lines: service_container/factories.rst
+36-22Lines 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 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.