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