我将专注于 Zend 框架,因为我最了解它,但这当然适用于其他使用控制反转容器的 PHP 框架中的其他类似机制。
在 Zend Framework 的情况下,通过一些重构/操作,完全可以不使用容器。
工作示例
$container
查看文档,目前 Zend Framework 正在使用(取自此处)做这样的事情:
function getServiceConfig()
{
return [
'factories' => [
Model\AlbumTable::class => function ($container)
{
$tableGateway = $container->get(Model\AlbumTableGateway::class);
return new Model\AlbumTable($tableGateway);
},
Model\AlbumTableGateway::class => function ($container)
{
$dbAdapter = $container->get(AdapterInterface::class);
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Model\Album());
return new TableGateway('album', $dbAdapter, null, $resultSetPrototype);
}
]
];
}
//to call
$albumTable = $container->get(Model\AlbumTable::class)
左侧=>
包含“keys”,可以是任何字符串,包括类定义字符串。右侧是类名的回调或 FQDN。在上面的例子中,它是一个匿名的 PHP 函数,它就像一个工厂来实例化一个新实体,使用$container
通过框架调用传递给该函数的 DiC。
为什么不移除容器并执行以下操作:
//define
function AlbumTableFactory()
{
$tableGateway = AlbumTableGatewayFactory();
return new Model\AlbumTable($tableGateway);
}
function AlbumTableGatewayFactory()
{
$dbAdapter = AdapterInterface();
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Model\Album());
return new TableGateway('album', $dbAdapter, null, $resultSetPrototype);
}
//to call
$albumTable = AlbumTableFactory();
如果裸函数很麻烦,上面可以转换为类。
在上面我删除$container
并用硬编码函数调用替换了任何容器使用,new
因为没有提供参数
由于factories
数组是Zend 容器配置的一部分,要真正将其分解出来,我必须Model\AlbumTable::class
用工厂调用替换任何其他容器调用实例,以便返回Model\AlbumTable
实例。完成后,我可以有一个无容器的 Zend 实现,直接调用工厂,而不是通过显式定义所有依赖项的容器调用它们。
问题的精神是……为什么要使用容器,它到底提供了什么,为什么不使用“真正的 PHP 代码”,因为容器不会隐藏任何依赖关系。