在当前(2.1)ZF2用户指南的“Database and models”一章中有一段代码片段,我不明白:
(阻止“使用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。
指南中是错误还是我错误地理解了代码?
由于
答案 0 :(得分:3)
考虑这一点的最佳方法是ServiceManager的get()
方法采用键值,而不是类名。键值需要映射到将导致返回类实例的内容。
如果密钥在invokables
部分内,那么ServiceManager将尝试实例化该密钥所指向的字符串,前提是它是一个类名:
'invokables' => array(
'some_name' => 'My\Mapper\SomeClassName',
),
如果密钥在factories
部分内,则ServiceManager将执行密钥指向的回调并期望返回对象实例:
'factories' => array(
'some_name' => function($sm) { return new \My\Mapper\SomeClassName(); },
),
一般情况下,当你需要做的不仅仅是实例化一个类时,你使用工厂 - 通常你需要用另一个依赖项来设置类。如果您只需要实例化一个类,请使用invokable。