我昨天读了这篇文章:https://igor.io/2012/11/09/scaling-silex.html
另一个http://davedevelopment.co.uk/2012/10/03/Silex-Controllers-As-Services.html
所以一个概念性的问题在我脑海中浮现:
目前我在不同的课程中有很多控制器。我覆盖controller_resolver
来创建一个控制器类实例,并将$app
注入到contoller的构造函数中。
我定义了这样的路由$app->get('/hello', 'HelloController::indexAction')
< - 我的控制器解析器将创建new HelloController($app);
- 到目前为止一切都很好。
但说实话,它变成了ServiceLocator模式,而不是DependencyInjection,因为我注入了整个$app
,看起来像ServiceLocator用法。
现在我有疑问:我应该保持原样(因为它运行良好)或尝试“控制器作为服务”只注入我的控制器真正依赖的服务?可能是我的SeviceLocator方法有一天会打我? (人们说DI更适合测试)。
我也研究过Symfony Framework Bundle:类Controller
扩展了抽象类ContainerAware
,它也注入了整个$container
!完全堆栈框架中的ServiceLocator方法?
任何推荐?优点/缺点?
答案 0 :(得分:4)
框架使用依赖注入模式而不是服务定位器模式。
默认情况下,所有控制器都不是服务。 ContainerAware
类包括访问服务容器的方法,因此您可以在Controller中调用Services。
如果您要将Controller用作服务,则需要删除Controller
扩展。您希望在控制器中使用的所有依赖项都需要由服务容器注入。
在a blogpost by richard miller中了解更多相关信息,这是Symfony2的核心贡献者之一。
Silex微框架提供了框架的基础,它取决于架构的外观和使用的模式。
Silex文档使用非服务的控制器。它在Controller中注入了完整的Service Container:
$app->post('/post/{id}-{slug}', function($id, $slug) use ($app) {
// ...
});
如果您想将控制器用作服务,则只应在控制器中注入要使用的服务。
编辑:Controller::action
语法也指不是服务的控制器。 Controller:action
表示法用于将控制器称为服务。
答案 1 :(得分:1)
这里涉及很多个人偏好。您已经完成的工作是组织代码库的一个很好的(足够的)步骤。有些人喜欢我自己更进一步,将控制器移动到容器,而不是将其注入某种BaseController。这在Silex和完整堆栈Symfony框架中都会发生。
我的建议是保留您拥有的所有内容,然后尝试通过练习BDD将您的下一个控制器定义为服务。
例如,UserController视图操作的行为:
它没有提到从容器中检索数据库或模板渲染器。我很舒服没有注射容器,所以我只会注入我认为我需要BDD的东西。