2

在当前(2.1)ZF2用户指南的“数据库和模型”一章中有一个代码片段,我不明白:

(块“使用ServiceManager配置表网关并注入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);
                },
            ),
        );
    }
}

该变量$sm稍后将成为 的实例Zend\ServiceManager\ServiceManager,对吗?Zend\ServiceManager\ServiceManager#get(...) 方法需要一个类名作为第一个参数。但是没有类 AlbumTableGateway。只有两个模型类:Album\Model\Album 和 Album\Model\AlbumTable。

这是指南中的错误还是我错误地理解了代码?

谢谢

4

1 回答 1

3

想到这一点的最好方法是 ServiceManager 的get()方法采用键值,而不是类名。键值需要映射到将导致返回类实例的内容。

如果键在该invokables部分内,则 ServiceManager 将尝试实例化键指向的字符串,假设它是一个类名:

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

如果 key 在factoriessection 内,则 ServiceManager 将执行 key 指向的回调并期望返回一个对象实例:

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

通常,当您需要做的不仅仅是实例化一个类时,您会使用工厂 - 通常您需要使用另一个依赖项设置该类。如果您只需要实例化一个类,请使用可调用的。

于 2013-02-25T08:56:11.763 回答