Zend\ServiceManager is usually configured in two places: an array in a config file or a method within your Module class. In either case, you provide a nested array of configuration information.
For example, in a config file:
return array(
'service_manager' => array(
'invokables' => array(
'session' => 'ZendSessionStorageSessionStorage',
),
'factories' => array(
'db' => 'ZendDbAdapterAdapterServiceFactory',
),
)
);
Within the service_manager array, there are a set of nested arrays which are generally used to configure how you want a given class to be instantiated. the names of these sub-arrays are hardcoded, so you just need to learn their names and the difference between them:
invokables
A string which is the name of a class to be instantiated. The ServiceManager will instantiate the class for you when needed. For example:
'invokables' => array(
'zfcuser_user' => 'UserServiceUser'
),
|
services
An instance of a class. This is used to register already instantiated objects with the ServiceManager. For example:
'services' => array(
'rob' => $rob, // $rob is already instantiated
),
|
factories
A callback that will return an instantiated class. This is for cases where you need to configure the instance of the object. For example:
'factories' => array(
'MyModuleMapperComment' => function($sm) {
$mapper = new MyModuleMapperComment();
$db = $sm->get('ZendDbAdapterAdapter');
$mapper->setDbAdapter($db);
return $mapper;
},
),
|
aliases
Another name for a class. Generally, you see this used within a module so that the module uses it’s own alias name and then the user of the module can configure exactly which class that alias name is to be.
For example:
'aliases' => array(
'mymodule_zend_db_adapter' => 'ZendDbAdapterAdapter',
),
|
initializers
A callback that is executed every time the ServiceManager creates a new instance of a class. These are usually used to inject an object into the new class instance if that class implements a particular interface.
For example:
'initializers' => array(
function ($instance, $sm) {
if ($instance instanceof AuthorizeAwareInterface) {
$instance->setAuthorizeService($sm->get('auth_service'));
}
}
)
In this case, the initialiser checks if $instance implements AuthorizeAwareInterface and if it injects the Authorize service into the instance ready for use. Another really common use-case is injecting a database adapter and Zend Framework supplies ZendDbAdapterAdapterAwareInterface for this case.
|
There is also the abstract_factories key, but this is rarely used in most apps.
abstract_factories
A factory instance that can create multiple services based on the name supplied to the factory. This is used to enable ServiceManager to fallback to another Service Locator system if it can cannot locate the required class from within its own configuration. As an example, you could write an abstract factory that proxies to Symfony’s DependencyInjection component. Items within this sub-key can be either a classname string or an instance of the factory itself For example:
array('abstract_factories' => array(
new DiStrictAbstractServiceFactory(),
);
All abstract factories must implement ZendServiceManagerAbstractFactoryInterface.
|
Controllers, View helpers & Controller plugins
Note that the MVC system instantiates controllers, view helpers, form elements, input filters, controller plugins and others using specialised versions of ServiceManager. This means that the same keys that you use for service manager configuration are used for setting up view helpers and controller plugins, etc. – you just use a different top level configuration key and method name the in Module class:
Manager |
Key name in configuration array |
Method name in Module.php |
ServiceManager |
service_manager |
getServiceConfig() |
ViewHelperManager |
view_helpers |
getViewHelperConfig() |
ControllerPluginManager |
controller_plugins |
getControllerPluginConfig() |
ControllerManager |
controllers |
getControllerConfig() |
ValidatorManager |
validators |
getValidatorConfig() |
FilterManager |
filters |
getFilterConfig() |
FormElementManager |
form_elements |
getFormElementConfig() |
RoutePluginManager |
route_manager |
getRouteConfig() |
SerializerAdapterManager |
serializers |
getSerializerConfig() |
HydratorManager |
hydrators |
getHydratorConfig() |
InputFilterManager |
input_filters |
getInputFilterConfig() |
This is reuse of knowledge at its best!
Thanks! That was exactly what I was looking for three days ago!
That will save me a lot of time!
The following will be added in ZF 2.1:
Manager : FormElementManager
Key name in configuration array : form_elements
Method name in Module.php : getFormElementConfig
Great tutorial, I finally find article about service initializer, Thanks.
Thanks, Rob!
so, the [services] have to be used with either [factories] or [invokables] ?
if [services] register already instantiated objects, those objects can be already instantiated only by either a [factory] of an [invokable] at that configuration level, right?
thanks for the tutorial.
Thank you Rob! Hard to think people could ever do without this overview.
Doesn't getControllerConfig() use an instance of ControllerManager? I know that is what I've been using.
Michael,
You're right.
The key in the SM is ControllerLoader, but it's an instance of ControllerManager and it's created in the ControllerLoaderFactory class.
Regards,
Rob…