zend framework 2 service manager difference between invokables and factories

5.3k Views Asked by At

Hi i'm new to zend framework. try to catch up on the service manager. base on the zend framework documentation , it said:

factories, an array of service name/factory class name pairs. The factories should be either classes implementing Zend\ServiceManager\FactoryInterface or invokable classes. If you are using PHP configuration files, you may provide any PHP callable as the factory.

invokables, an array of service name/class name pairs. The class name should be class that may be directly instantiated without any constructor arguments.

but i'm still don't quit understand the different beween them. when i should use as invokeable and when i should use factories? what is advantage use factories? thanks very much.

1

There are 1 best solutions below

1
On BEST ANSWER

The invokables should be used to instantiate a sinmple object, which doesn't need any other dependencies etc in the contstructor.

You should use a factory when there's a little more complex logic behind instantiating the object. Moving the code into a factory will save you duplicating the code when ever you need an object back too.

Factory example:

    'factories' => array(
        'Application\Acl' => 'Application\Service\AclFactory',

AclFactory.php

namespace Application\Service;

use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\Permissions\Acl\Resource\GenericResource;
use Zend\Permissions\Acl\Role\GenericRole;

class AclFactory implements FactoryInterface
{
     /**
     * Create a new ACL Instance
     *
     * @param ServiceLocatorInterface $serviceLocator
     * @return Demande
     */
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $acl = new \Zend\Permissions\Acl\Acl();
        /**
         * Here you can setup Resources, Roles or some other stuff.
         * If it's complex you can make a factory like this to keep
         * the code out of the service config, and it will save you 
         * having to duplicate the code when ever you need your ACL
         */

        return $acl;
    }

}

If you want back a simple class/object back then you can just use an invokable, as there's no boiler-plate code needed to get the object back.

'invokables' => array(
    'MyClass'          => 'Application\Model\MyClass',

another Example, with controllers:

If you have a simple controller, with no requried dependencies, use an invokable:

'invokables' => array(
    'index'          => 'Mis\Controller\IndexController',

But sometimes you want to add extra dependencies to the controller when you instantiate it:

'factories' => array(
        /**
         * This could also be added as a Factory as in the example above to
         * move this code out of the config file..
         */
        //'users' => 'Application\Service\UsersControllerFactory',
        'users' => function($sm) {
            $controller = new \Application\Controller\UsersController();
            $controller->setMapper($sm->getServiceLocator()->get('UserMapper'));
            $controller->setForm($sm->getServiceLocator()->get('UserForm'));

            return $controller;
        },