什么时候说“在构造函数中”是指传入 conatiner 并从中提取依赖项(在构造函数中)?
<?php
class SomeController
{
public function __construct($container)
{
$this->service1 = $contanier->get('service1);
}
//...
}
我建议不要这样做,虽然更简单,但您可以将控制器耦合到 容器,从而使用 ServiceLocator 而不是真正的控制反转。
如果您希望您的控制器易于进行单元测试,您应该使用控制反转:
class SomeController
{
public function __construct($service1)
{
$this->service1 = $service1;
}
//...
}
您甚至可以将控制器创建为容器内的服务:
// this uses Pimple notation, I hope you get the point
$container['controller'] = function($c) {
return SomeController($c['service1']);
}
使用代理服务来延迟加载它们
此外,如果您的控制器需要的不仅仅是某些服务,而且您不会使用所有这些服务,您可以:
1) 使用代理服务以便仅在真正需要时才延迟加载服务
<?php
class ProxyService
{
/**
* @var Service1Type
*/
private $actualService;
public function __construct()
{
$this->actualService = null;
}
private function initialize()
{
$this->actualService = new Service1(); // This operation may take some time thus we deferred as long as possible
}
private function isInitialized()
{
return $this->actualService === null;
}
public function someActionOnThisService()
{
if (!$this->isInitalized()) {
$this->initalize();
}
$this->actualService->someActionOnThisService();
}
你有一个带有延迟加载的简单代理对象。如果你想走那条路,你可能想看看很棒的Proxy Manager Library
2) 拆分你的控制器
如果您的控制器有太多依赖项,您可能需要拆分它。
事实上,您可能想阅读Paul M. Jones(Aura Framework 的首席开发人员)关于MVC-Refinement 的提案,恕我直言,尽管您可能不完全同意,但它是一本不错的读物。
即使您拆分控制器以减少依赖项,延迟加载您的依赖项也是一个好主意(显然,如果它在您的上下文中可行,您必须检查天气:更多工作以获得更快的速度)。