Configure dependency injection in Zend Framework 2 using annotations/yaml/xml.
Idea based on the JMSDiExtraBundle for the Symfony2 project.
-
Install with Composer:
composer require mikemix/mxdi-module:~3.0
(rules of semantic versioning apply). -
Enable the module via ZF2 config in
appliation.config.php
undermodules
key:return [ // // 'modules' => [ 'mxdiModule', // other modules ], // // ];
This will enable the module and register the Abstract Factory in the ZF2's Service Manager.
-
Copy the global config file
cp vendor/mikemix/mxdi-module/resources/mxdimodule.global.php.dist config/autoload/mxdimodule.global.php
if you want to override the default mapping driver. -
Copy the local config file
cp vendor/mikemix/mxdi-module/resources/mxdimodule.local.php.dist config/autoload/mxdimodule.local.php
if you want to override other settings, like caching etc.
The default mapping driver is AnnotationExtractor
as source of mapping information for the module. You can change it however to other. Available extractors are:
AnnotationExtractor
(default) which uses annotations inside your classes. See the Annotation docs for annotations reference and examples.YamlExtractor
which uses a yml file. See the YAML docs for examples.XmlExtractor
which uses a xml file. See the XML docs for examples.
There's no difference between choosing annotation driver or YAML or XML driver, because the mapping information in the end is converted to plain php and stored inside the cache.
Remember, the requested service must not be registered in the Service Manager. If you register it as factory or invokable, it won't go through the Abstract Factory and won't get injected. By the way, this allows you to create custom factory for the service in mention.
To speed up locate time you can request the service through the DiFactory invokable, for example:
/** @var \mxdiModule\Service\DiFactory @factory */
$factory = $this->getServiceLocator()->get(\mxdiModule\Service\DiFactory::class);
/** @var \YourApplication\Service\SomeService $service */
$service = $factory(\YourApplication\Service\SomeService::class);
Parsing mapping sources is very heavy. You should enable the cache on production servers.
You can set up caching easily with any custom or pre-existing ZF2 cache adapter. In the config/autoload/mxdimodule.local.php
override the cache_adapter
and cache_options
keys for your needs. You can find more information about available out-of-the-box adapters at the ZF2 docs site.
If you get ServiceNotCreated exception most probably one of your injections is not registered in the ZF2's Service Manager. In the exception stack you will see some more detailed information. For instance look for CannotGetValue exceptions.
-
Clear generated proxy files:
php public/index.php mxdimodule proxy clear
Clear all generated proxy files from the proxy dir
-
Clear annotation parsing cache:
php public/index.php mxdimodule cache clear [<fqcn>]
Flush whole cache or only of a given service