在Symfony2中,服务定义为[强调矿]:
服务是任何执行具体任务。服务通常使用"全局",例如数据库连接对象或传递电子邮件的对象。在Symfony2中,服务通常是从服务容器。具有许多解耦服务的应用程序是据说遵循面向服务的体系结构。
以"全局"为关键词,我看到的所有关于如何定义服务的示例都在现有捆绑包中声明了服务?以下是MartinSikora.com 的一个例子
<?php
// Bundle/HelloBundle/Services/MyService.php
namespace Bundle'HelloBundle'Services;
class MyService {
public function sum($n1, $n2) {
return $n1 + $n2;
}
}
?>
然后,他在Hello控制器中使用它:
<?php
// Bundle/HelloBundle/Controller/HelloController.php
namespace Bundle'HelloBundle'Controller;
class HelloController extends Controller {
public function indexAction() {
$number = $this->get('my_service')->sum(12, 37);
// this returns 49
/*
...
*/
}
}
?>
注意他的示例服务是如何在HelloBundle捆绑包中的一个标记为"Services"的文件夹中声明的。如果"服务"文件夹存储在任何特定捆绑包之外的一个或多个更高级别,那不是更好吗?因为服务是指在整个应用程序中使用的?
- 这里的最佳做法是什么
- 该服务是否仅适用于HelloBundle捆绑包中的控制器
- 为什么通常是这样做的
简短回答
不需要,服务不需要在捆绑包中定义。实际的服务类可能存在也可能不存在于捆绑包中——它们可能存在于供应商库文件夹中(或其他任何位置)。服务定义虽然通常在捆绑包的Resources'config'services.yml
中定义,但也可以在services
密钥下的app/config.yml
中定义。
服务只是一个已经在Symfony的依赖注入容器中注册的类。班级本身可以住在任何地方。
长答案
理解Symfony2中捆绑包的用途非常重要。您的项目的大部分(主要的例外是第三方库)都是由捆绑包组成的。有些人喜欢把所有东西放在一个巨大的捆绑包里,但我更喜欢把它们用作特定功能的容器(即:用户管理、博客文章管理、资产管理)
因为bundle应该代表一部分功能,所以在bundle中定义一些服务是有意义的。例如,在BlogPostBundle
中定义BlogPostEntityService
类是很自然的。现在,仅仅因为服务包含在捆绑包中,并不会降低它的全局性。如果我将服务注册为blog_bundle.blog_post_entity_service
,我仍然可以从任何其他捆绑包访问它。
在Martin的例子中,MyService
是一个模糊的例子——它不像BlogPostEntityService
那样具体。但是,您可能会创建实用程序服务(即ArrayUtilService
),在这种情况下,您可能希望创建一个UtilBundle
并将服务存储在那里。
这里的最佳做法是什么?
没有明确的答案——由您决定将服务类存储在哪里。问问自己,服务是否直接处理捆绑包所代表的功能——如果是,它很可能属于捆绑包。如果您计划共享或重用捆绑包,这也是有意义的。
该服务是否仅对HelloBundle中的控制器可用捆
没有。您可以从任何控制器(或任何支持container
的类)中调用该服务。您还可以将MyService
注入到任何其他服务中。