Skip to content

Commit f748378

Browse files
committed
feature #4498 Use new factory syntax (WouterJ)
This PR was merged into the 2.6 branch. Discussion ---------- Use new factory syntax | Q | A | --- | --- | Doc fix? | no | New docs? | yes (symfony/symfony#12008) | Applies to | 2.6+ | Fixed tickets | #4291 Commits ------- 9cbcc2b Applied fixes d7998b0 Use new factory syntax
2 parents 59f0374 + 9cbcc2b commit f748378

File tree

1 file changed

+53
-104
lines changed

1 file changed

+53
-104
lines changed

components/dependency_injection/factories.rst

+53-104
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
Using a Factory to Create Services
55
==================================
66

7+
.. versionadded:: 2.6
8+
The new `Symfony\\Component\\DependencyInjection\\Definition::setFactory`
9+
method was introduced in Symfony 2.6. Refer to older versions for the
10+
syntax for factories prior to 2.6.
11+
712
Symfony's Service Container provides a powerful way of controlling the
813
creation of objects, allowing you to specify arguments passed to the constructor
914
as well as calling methods and setting parameters. Sometimes, however, this
@@ -15,9 +20,9 @@ the class.
1520
Suppose you have a factory that configures and returns a new ``NewsletterManager``
1621
object::
1722

18-
class NewsletterFactory
23+
class NewsletterManagerFactory
1924
{
20-
public function get()
25+
public static function createNewsletterManager()
2126
{
2227
$newsletterManager = new NewsletterManager();
2328

@@ -28,22 +33,17 @@ object::
2833
}
2934

3035
To make the ``NewsletterManager`` object available as a service, you can
31-
configure the service container to use the ``NewsletterFactory`` factory
32-
class:
36+
configure the service container to use the
37+
``NewsletterFactory::createNewsletterManager()`` factory method:
3338

3439
.. configuration-block::
3540

3641
.. code-block:: yaml
3742
38-
parameters:
39-
# ...
40-
newsletter_manager.class: NewsletterManager
41-
newsletter_factory.class: NewsletterFactory
4243
services:
4344
newsletter_manager:
44-
class: "%newsletter_manager.class%"
45-
factory_class: "%newsletter_factory.class%"
46-
factory_method: get
45+
class: NewsletterManager
46+
factory: [NewsletterManagerFactory, createNewsletterManager]
4747
4848
.. code-block:: xml
4949
@@ -52,18 +52,10 @@ class:
5252
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5353
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
5454
55-
<parameters>
56-
<!-- ... -->
57-
<parameter key="newsletter_manager.class">NewsletterManager</parameter>
58-
<parameter key="newsletter_factory.class">NewsletterFactory</parameter>
59-
</parameters>
60-
6155
<services>
62-
<service
63-
id="newsletter_manager"
64-
class="%newsletter_manager.class%"
65-
factory-class="%newsletter_factory.class%"
66-
factory-method="get" />
56+
<service id="newsletter_manager" class="NewsletterManager">
57+
<factory class="NewsletterManagerFactory" method="createNewsletterManager" />
58+
</service>
6759
</services>
6860
</services>
6961
@@ -72,35 +64,26 @@ class:
7264
use Symfony\Component\DependencyInjection\Definition;
7365
7466
// ...
75-
$container->setParameter('newsletter_manager.class', 'NewsletterManager');
76-
$container->setParameter('newsletter_factory.class', 'NewsletterFactory');
77-
78-
$definition = new Definition('%newsletter_manager.class%');
79-
$definition->setFactoryClass('%newsletter_factory.class%');
80-
$definition->setFactoryMethod('get');
67+
$definition = new Definition('NewsletterManager');
68+
$definition->setFactory(array('NewsletterManagerFactory', 'createNewsletterManager'));
8169
8270
$container->setDefinition('newsletter_manager', $definition);
8371
84-
When you specify the class to use for the factory (via ``factory_class``)
85-
the method will be called statically. If the factory itself should be instantiated
86-
and the resulting object's method called, configure the factory itself as a service.
87-
In this case, the method (e.g. get) should be changed to be non-static:
72+
Now, the method will be called statically. If the factory class itself should
73+
be instantiated and the resulting object's method called, configure the factory
74+
itself as a service. In this case, the method (e.g. get) should be changed to
75+
be non-static.
8876

8977
.. configuration-block::
9078

9179
.. code-block:: yaml
9280
93-
parameters:
94-
# ...
95-
newsletter_manager.class: NewsletterManager
96-
newsletter_factory.class: NewsletterFactory
9781
services:
98-
newsletter_factory:
99-
class: "%newsletter_factory.class%"
82+
newsletter_manager.factory:
83+
class: NewsletterManagerFactory
10084
newsletter_manager:
101-
class: "%newsletter_manager.class%"
102-
factory_service: newsletter_factory
103-
factory_method: get
85+
class: NewsletterManager
86+
factory: ["@newsletter_manager.factory", createNewsletterManager]
10487
10588
.. code-block:: xml
10689
@@ -109,47 +92,29 @@ In this case, the method (e.g. get) should be changed to be non-static:
10992
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
11093
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
11194
112-
<parameters>
113-
<!-- ... -->
114-
<parameter key="newsletter_manager.class">NewsletterManager</parameter>
115-
<parameter key="newsletter_factory.class">NewsletterFactory</parameter>
116-
</parameters>
117-
11895
<services>
119-
<service id="newsletter_factory" class="%newsletter_factory.class%"/>
96+
<service id="newsletter_manager.factory" class="NewsletterManagerFactory" />
12097
121-
<service
122-
id="newsletter_manager"
123-
class="%newsletter_manager.class%"
124-
factory-service="newsletter_factory"
125-
factory-method="get" />
98+
<service id="newsletter_manager" class="NewsletterManager">
99+
<factory service="newsletter_manager.factry" method="createNewsletterManager" />
100+
</service>
126101
</services>
127102
</container>
128103
129104
.. code-block:: php
130105
106+
use Symfony\Component\DependencyInjection\Reference;
131107
use Symfony\Component\DependencyInjection\Definition;
132108
133109
// ...
134-
$container->setParameter('newsletter_manager.class', 'NewsletterManager');
135-
$container->setParameter('newsletter_factory.class', 'NewsletterFactory');
110+
$container->register('newsletter_manager.factory', 'NewsletterManagerFactory');
136111
137-
$container->setDefinition('newsletter_factory', new Definition(
138-
'%newsletter_factory.class%'
112+
$newsletterManager = new Definition();
113+
$newsletterManager->setFactory(array(
114+
new Reference('newsletter_manager.factory'),
115+
'createNewsletterManager'
139116
));
140-
$container->setDefinition('newsletter_manager', new Definition(
141-
'%newsletter_manager.class%'
142-
))->setFactoryService(
143-
'newsletter_factory'
144-
)->setFactoryMethod(
145-
'get'
146-
);
147-
148-
.. note::
149-
150-
The factory service is specified by its id name and not a reference to
151-
the service itself. So, you do not need to use the @ syntax for this in
152-
YAML configurations.
117+
$container->setDefinition('newsletter_manager', $newsletterManager);
153118
154119
Passing Arguments to the Factory Method
155120
---------------------------------------
@@ -162,17 +127,13 @@ in the previous example takes the ``templating`` service as an argument:
162127

163128
.. code-block:: yaml
164129
165-
parameters:
166-
# ...
167-
newsletter_manager.class: NewsletterManager
168-
newsletter_factory.class: NewsletterFactory
169130
services:
170-
newsletter_factory:
171-
class: "%newsletter_factory.class%"
131+
newsletter_manager.factory:
132+
class: NewsletterManagerFactory
133+
172134
newsletter_manager:
173-
class: "%newsletter_manager.class%"
174-
factory_service: newsletter_factory
175-
factory_method: get
135+
class: NewsletterManager
136+
factory: ["@newsletter_manager.factory", createNewsletterManager]
176137
arguments:
177138
- "@templating"
178139
@@ -183,42 +144,30 @@ in the previous example takes the ``templating`` service as an argument:
183144
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
184145
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
185146
186-
<parameters>
187-
<!-- ... -->
188-
<parameter key="newsletter_manager.class">NewsletterManager</parameter>
189-
<parameter key="newsletter_factory.class">NewsletterFactory</parameter>
190-
</parameters>
191-
192147
<services>
193-
<service id="newsletter_factory" class="%newsletter_factory.class%"/>
148+
<service id="newsletter_manager.factory" class="NewsletterManagerFactory"/>
194149
195-
<service
196-
id="newsletter_manager"
197-
class="%newsletter_manager.class%"
198-
factory-service="newsletter_factory"
199-
factory-method="get">
200-
201-
<argument type="service" id="templating" />
150+
<service id="newsletter_manager" class="NewsletterManager">
151+
<factory service="newsletter_manager.factory" method="createNewsletterManager"/>
152+
<argument type="service" id="templating"/>
202153
</service>
203154
</services>
204155
</container>
205156
206157
.. code-block:: php
207158
159+
use Symfony\Component\DependencyInjection\Reference;
208160
use Symfony\Component\DependencyInjection\Definition;
209161
210162
// ...
211-
$container->setParameter('newsletter_manager.class', 'NewsletterManager');
212-
$container->setParameter('newsletter_factory.class', 'NewsletterFactory');
163+
$container->register('newsletter_manager.factory', 'NewsletterManagerFactory');
213164
214-
$container->setDefinition('newsletter_factory', new Definition(
215-
'%newsletter_factory.class%'
216-
));
217-
$container->setDefinition('newsletter_manager', new Definition(
218-
'%newsletter_manager.class%',
165+
$newsletterManager = new Definition(
166+
'NewsletterManager',
219167
array(new Reference('templating'))
220-
))->setFactoryService(
221-
'newsletter_factory'
222-
)->setFactoryMethod(
223-
'get'
224168
);
169+
$newsletterManager->setFactory(array(
170+
new Reference('newsletter_manager.factory'),
171+
'createNewsletterManager'
172+
));
173+
$container->setDefinition('newsletter_manager', $newsletterManager);

0 commit comments

Comments
 (0)