On this page
Cookbook
Automating Controller Factories
Writing a factory class for each and every controller that has dependencies can be tedious, particularly in early development as you are still sorting out dependencies.
As of version 3.0.1, laminas-mvc ships with Laminas\Mvc\Controller\LazyControllerAbstractFactory
,
which provides a reflection-based approach to controller instantiation,
resolving constructor dependencies to the relevant services. The factory may be
used as either an abstract factory, or mapped to specific controller names as a
factory:
use Laminas\Mvc\Controller\LazyControllerAbstractFactory;
return [
/* ... */
'controllers' => [
'abstract_factories' => [
LazyControllerAbstractFactory::class,
],
'factories' => [
'MyModule\Controller\FooController' => LazyControllerAbstractFactory::class,
],
],
/* ... */
];
Mapping controllers to the factory is more explicit and performant.
The factory operates with the following constraints/features:
- A parameter named
$config
typehinted as an array will receive the application "config" service (i.e., the merged configuration). - Parameters typehinted against array, but not named
$config
, will be injected with an empty array. - Scalar parameters will be resolved as null values.
- If a service cannot be found for a given typehint, the factory will raise an exception detailing this.
- Some services provided by Laminas components do not have
entries based on their class name (for historical reasons); the
factory contains a map of these class/interface names to the
corresponding service name to allow them to resolve. These include:
Laminas\Console\Adapter\AdapterInterface
maps toConsoleAdapter
,Laminas\Filter\FilterPluginManager
maps toFilterManager
,Laminas\Hydrator\HydratorPluginManager
maps toHydratorManager
,Laminas\InputFilter\InputFilterPluginManager
maps toInputFilterManager
,Laminas\Log\FilterPluginManager
maps toLogFilterManager
,Laminas\Log\FormatterPluginManager
maps toLogFormatterManager
,Laminas\Log\ProcessorPluginManager
maps toLogProcessorManager
,Laminas\Log\WriterPluginManager
maps toLogWriterManager
,Laminas\Serializer\AdapterPluginManager
maps toSerializerAdapterManager
,Laminas\Validator\ValidatorPluginManager
maps toValidatorManager
,
$options
passed to the factory are ignored in all cases, as we cannot
make assumptions about which argument(s) they might replace.
Once your dependencies have stabilized, we recommend writing a dedicated factory, as reflection can introduce performance overhead.
References
This feature was inspired by a blog post by Alexandre Lemaire.