您还可以使用 ControllerFatory,在其中提供给您的应用程序或路由器/调度程序
你可以调用 $controllerFactory->createController($name);
您的应用程序不知道如何创建 Factory 的控制器。由于您可以将自己的 ControllerFactory 注入到 DI 容器中,因此您可以根据控制器管理所需的所有依赖项。
class ControllerFactory {
public function __construct(EvenDispatcher $dispatcher,
Request $request,
ResponseFactory $responseFactory,
ModelFactory $modelFactory,
FormFactory $formFactory) {
...
}
public function createController($name = 'Default') {
switch ($name) {
case 'User':
return new UserController($dispatcher,
$request,
$responseFactory->createResponse('Html'),
$modelFactory->createModel('User'),
$formFactory->createForm('User'),...);
break;
case 'Ajax':
return new AjaxController($dispatcher,
$request,
$responseFactory->createResponse('Json'),
$modelFactory->createModel('User'));
break;
default:
return new DefaultController($dispatcher, $request, $responseFactory->createResponse('Html'));
}
}
}
所以你只需要在你的 DI 容器中添加这个工厂并将它传递给你的应用程序。每当您需要一个新控制器时,您将其添加到工厂,如果需要新的依赖项,您可以通过 DI 容器将它们提供给工厂。
class App {
public function __construct(Router $router,Request $request, ControllerFactory $cf, ... ) {
...
}
public function execute() {
$controllerName = $this->router->getMatchedController();
$actionName $this->router->getMatchedAction();
$controller = $cf->createController($controllerName);
if(is_callable($controller, $actionName)) {
$response = $controller->$action(request);
$response->send();
}
}
}
这不是生产代码,我还没有测试过,但这是您将控制器与应用程序分离的方式。请注意,这里有一个糟糕的耦合,因为我的控制器返回的是响应,而我在 App 中执行了响应。但就像我说的,这只是一个小例子。
将模型、表单和控制器的工厂传递给它们各自的父级通常是一个好主意,因为您最终会在引导时加载所有对象图,这确实很糟糕并且很消耗内存。
我知道这个答案已经被批准,但这是我在这个问题上的 2 美分
有一篇关于这个主题的好文章
http://miller.limethinking.co.uk/2011/07/07/dependency-injection-moving-from-basics-to-container/