4
4
Using a Factory to Create Services
5
5
==================================
6
6
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
+
7
12
Symfony's Service Container provides a powerful way of controlling the
8
13
creation of objects, allowing you to specify arguments passed to the constructor
9
14
as well as calling methods and setting parameters. Sometimes, however, this
@@ -15,9 +20,9 @@ the class.
15
20
Suppose you have a factory that configures and returns a new ``NewsletterManager ``
16
21
object::
17
22
18
- class NewsletterFactory
23
+ class NewsletterManagerFactory
19
24
{
20
- public function get ()
25
+ public static function createNewsletterManager ()
21
26
{
22
27
$newsletterManager = new NewsletterManager();
23
28
@@ -28,22 +33,17 @@ object::
28
33
}
29
34
30
35
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 :
33
38
34
39
.. configuration-block ::
35
40
36
41
.. code-block :: yaml
37
42
38
- parameters :
39
- # ...
40
- newsletter_manager.class : NewsletterManager
41
- newsletter_factory.class : NewsletterFactory
42
43
services :
43
44
newsletter_manager :
44
- class : " %newsletter_manager.class%"
45
- factory_class : " %newsletter_factory.class%"
46
- factory_method : get
45
+ class : NewsletterManager
46
+ factory : [NewsletterManagerFactory, createNewsletterManager]
47
47
48
48
.. code-block :: xml
49
49
@@ -52,18 +52,10 @@ class:
52
52
xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
53
53
xsi : schemaLocation =" http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd" >
54
54
55
- <parameters >
56
- <!-- ... -->
57
- <parameter key =" newsletter_manager.class" >NewsletterManager</parameter >
58
- <parameter key =" newsletter_factory.class" >NewsletterFactory</parameter >
59
- </parameters >
60
-
61
55
<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 >
67
59
</services >
68
60
</services >
69
61
@@ -72,35 +64,26 @@ class:
72
64
use Symfony\Component\DependencyInjection\Definition;
73
65
74
66
// ...
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'));
81
69
82
70
$container->setDefinition('newsletter_manager', $definition);
83
71
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.
88
76
89
77
.. configuration-block ::
90
78
91
79
.. code-block :: yaml
92
80
93
- parameters :
94
- # ...
95
- newsletter_manager.class : NewsletterManager
96
- newsletter_factory.class : NewsletterFactory
97
81
services :
98
- newsletter_factory :
99
- class : " %newsletter_factory.class% "
82
+ newsletter_manager.factory :
83
+ class : NewsletterManagerFactory
100
84
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]
104
87
105
88
.. code-block :: xml
106
89
@@ -109,47 +92,29 @@ In this case, the method (e.g. get) should be changed to be non-static:
109
92
xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
110
93
xsi : schemaLocation =" http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd" >
111
94
112
- <parameters >
113
- <!-- ... -->
114
- <parameter key =" newsletter_manager.class" >NewsletterManager</parameter >
115
- <parameter key =" newsletter_factory.class" >NewsletterFactory</parameter >
116
- </parameters >
117
-
118
95
<services >
119
- <service id =" newsletter_factory " class =" %newsletter_factory.class% " />
96
+ <service id =" newsletter_manager.factory " class =" NewsletterManagerFactory " />
120
97
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 >
126
101
</services >
127
102
</container >
128
103
129
104
.. code-block :: php
130
105
106
+ use Symfony\Component\DependencyInjection\Reference;
131
107
use Symfony\Component\DependencyInjection\Definition;
132
108
133
109
// ...
134
- $container->setParameter('newsletter_manager.class', 'NewsletterManager');
135
- $container->setParameter('newsletter_factory.class', 'NewsletterFactory');
110
+ $container->register('newsletter_manager.factory', 'NewsletterManagerFactory');
136
111
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'
139
116
));
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);
153
118
154
119
Passing Arguments to the Factory Method
155
120
---------------------------------------
@@ -162,17 +127,13 @@ in the previous example takes the ``templating`` service as an argument:
162
127
163
128
.. code-block :: yaml
164
129
165
- parameters :
166
- # ...
167
- newsletter_manager.class : NewsletterManager
168
- newsletter_factory.class : NewsletterFactory
169
130
services :
170
- newsletter_factory :
171
- class : " %newsletter_factory.class%"
131
+ newsletter_manager.factory :
132
+ class : NewsletterManagerFactory
133
+
172
134
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]
176
137
arguments :
177
138
- " @templating"
178
139
@@ -183,42 +144,30 @@ in the previous example takes the ``templating`` service as an argument:
183
144
xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
184
145
xsi : schemaLocation =" http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd" >
185
146
186
- <parameters >
187
- <!-- ... -->
188
- <parameter key =" newsletter_manager.class" >NewsletterManager</parameter >
189
- <parameter key =" newsletter_factory.class" >NewsletterFactory</parameter >
190
- </parameters >
191
-
192
147
<services >
193
- <service id =" newsletter_factory " class =" %newsletter_factory.class% " />
148
+ <service id =" newsletter_manager.factory " class =" NewsletterManagerFactory " />
194
149
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" />
202
153
</service >
203
154
</services >
204
155
</container >
205
156
206
157
.. code-block :: php
207
158
159
+ use Symfony\Component\DependencyInjection\Reference;
208
160
use Symfony\Component\DependencyInjection\Definition;
209
161
210
162
// ...
211
- $container->setParameter('newsletter_manager.class', 'NewsletterManager');
212
- $container->setParameter('newsletter_factory.class', 'NewsletterFactory');
163
+ $container->register('newsletter_manager.factory', 'NewsletterManagerFactory');
213
164
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',
219
167
array(new Reference('templating'))
220
- ))->setFactoryService(
221
- 'newsletter_factory'
222
- )->setFactoryMethod(
223
- 'get'
224
168
);
169
+ $newsletterManager->setFactory(array(
170
+ new Reference('newsletter_manager.factory'),
171
+ 'createNewsletterManager'
172
+ ));
173
+ $container->setDefinition('newsletter_manager', $newsletterManager);
0 commit comments