Question

In the chapter "Database and models" of the current (2.1) ZF2 User Guide there a code snippet, I don't understand:

(block "Using ServiceManager to configure the table gateway and inject into the AlbumTable")

...
class Module
{
    // getAutoloaderConfig() and getConfig() methods here

    // Add this method:
    public function getServiceConfig()
    {
        return array(
            'factories' => array(
                'Album\Model\AlbumTable' =>  function($sm) {
                    $tableGateway = $sm->get('AlbumTableGateway');
                    $table = new AlbumTable($tableGateway);
                    return $table;
                },
                'AlbumTableGateway' => function ($sm) {
                    $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                    $resultSetPrototype = new ResultSet();
                    $resultSetPrototype->setArrayObjectPrototype(new Album());
                    return new TableGateway('album', $dbAdapter, null, $resultSetPrototype);
                },
            ),
        );
    }
}

The variable $sm will be later an instance of the Zend\ServiceManager\ServiceManager, right? The method Zend\ServiceManager\ServiceManager#get(...) expects a classname as first argument. But there is no class AlbumTableGateway. There are only two model classes: Album\Model\Album and Album\Model\AlbumTable.

Is it an error in the guide or am I understanding the code wrongly?

Thanks

Was it helpful?

Solution

The best way to think of this is that ServiceManager's get() method takes a key value, not a class name. The key value needs to map to something that will result in a class instance being returned.

If the key is within the invokables section, then the ServiceManager will try to instantiate the string that the key points to on the assumption that it's a classname:

'invokables' => array(
    'some_name' => 'My\Mapper\SomeClassName',
),

If the key is within the factories section, then the ServiceManager will execute the callback that the key points to and expect an object instance to be returned:

'factories' => array(
    'some_name' => function($sm) { return new \My\Mapper\SomeClassName(); },
),

In general, you use a factory when you need to do something more than just instantiate a class - usually you need to set up the class with another dependency. If you just need to instantiate a class, use an invokable.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top