Silex - 真正的DI vs注入$ app,看起来像ServiceLocator?

时间:2012-11-10 08:31:01

标签: symfony dependency-injection silex service-locator

我昨天读了这篇文章: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方法?

任何推荐?优点/缺点?

2 个答案:

答案 0 :(得分:4)

symfony2全栈框架

框架使用依赖注入模式而不是服务定位器模式。

默认情况下,所有控制器都不是服务。 ContainerAware类包括访问服务容器的方法,因此您可以在Controller中调用Services。

如果您要将Controller用作服务,则需要删除Controller扩展。您希望在控制器中使用的所有依赖项都需要由服务容器注入。

a blogpost by richard miller中了解更多相关信息,这是Symfony2的核心贡献者之一。

Silex微框架

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的东西。