@@ -103,3 +103,100 @@ injected by one of these initializers, and we plan to remove the initializers
103
103
for version 3.0. The deprecation notice includes the name of the class, to help
104
104
you identify what instances you will need to update before the zend-mvc v3
105
105
release.
106
+
107
+ To prepare your code, you will need to do the following within your controller:
108
+
109
+ - Find all cases where you call ` getServiceLocator() ` , and identify the services
110
+ they retrieve.
111
+ - Update your controller to accept these services via the constructor.
112
+ - If you have not already, create a factory class for your controller.
113
+ - In the factory, pull the appropriate services and pass them to the
114
+ controller's constructor.
115
+
116
+ As an example, consider the following code from a controller:
117
+
118
+ ``` php
119
+ $db = $this->getServiceLcoator()->get('Db\ApplicationAdapter');
120
+ ```
121
+
122
+ To update your controller, you will:
123
+
124
+ - Add a ` $db ` property to your class.
125
+ - Update the constructor to accept the database adapter and assign it to the
126
+ ` $db ` property.
127
+ - Change the above line to either read ` $db = $this->db; ` * or just use the
128
+ property directly* .
129
+ - Add a factory that pulls the service and pushes it into the controller.
130
+
131
+ The controller then might look like the following:
132
+
133
+ ``` php
134
+ use Zend\Db\Adapter\AdapterInterface;
135
+ use Zend\Mvc\Controller\AbstractActionController;
136
+
137
+ class YourController extends AbstractActionController
138
+ {
139
+ private $db;
140
+
141
+ public function __construct(AdapterInterface $db)
142
+ {
143
+ $this->db = $db;
144
+ }
145
+
146
+ public function someAction()
147
+ {
148
+ $results = $this->db->query(/* ... */);
149
+ /* ... */
150
+ }
151
+ }
152
+ ```
153
+
154
+ A factory would look like the following:
155
+
156
+ ``` php
157
+ use Interop\Container\ContainerInterface;
158
+
159
+ class YourControllerFactory
160
+ {
161
+ public function __invoke(ContainerInterface $container)
162
+ {
163
+ return new YourController($this->get('Db\ApplicationAdapter'));
164
+ }
165
+ }
166
+ ```
167
+
168
+ You then also need to ensure the controller manager knows about the factory. It
169
+ likely already does, as an invokable; you will redefine it as a factory in
170
+ your ` module.config.php ` :
171
+
172
+ ``` php
173
+ return [
174
+ 'controllers' => [
175
+ 'factories' => [
176
+ YourController::class => YourControllerFactory::class,
177
+ /* ... */
178
+ ],
179
+ /* ... */
180
+ ],
181
+ /* ... */
182
+ ];
183
+ ```
184
+
185
+ While this may seem like more steps, doing so ensures your code has no hidden
186
+ dependencies, improves the testability of your code, and allows you to substitute
187
+ alternatives for either the dependencies or the controller itself.
188
+
189
+ #### Optional dependencies
190
+
191
+ In some cases, you may have dependencies that are only required for some
192
+ execution paths, such as forms, database adapters, etc. In these cases, you have
193
+ two approaches you can use:
194
+
195
+ - Split your controller into separate responsibilities, and use the more
196
+ specific controllers. This way you don't need to inject dependencies that are
197
+ only used in some actions. (We recommend doing this regardless, as it helps
198
+ keep your code more maintainable.)
199
+ - Use [ lazy services] ( http://zendframework.github.io/zend-servicemanager/lazy-services/ ) .
200
+ When you configure these, zend-servicemanager gives you a proxy instance that,
201
+ on first access, loads the full service. This allows you to delay the most
202
+ expensive operations until absolutely needed.
0 commit comments