我会尽力解释服务,但是 Symfony2docs http://symfony.com/doc/current/book/service_container.html做得比我能做的更好。
从本质上讲,服务只是一个类。一个类在 Symfony2 中注册后就成为一个服务Dependency Injection Container
(要不就Container
简称。)此时,该类是应用程序服务层的一部分。
服务可能具有依赖性(而且很多时候确实如此),但这不是必需的。服务通常用作其他服务的依赖项。让我举一个例子:
- 您有一个用于发送电子邮件的类,名为
EmailSender
- 您有一个类,其中包含有关如何通过 SMTP 发送电子邮件的说明,称为
SmtpTransport
-
EmailSender
具有以下形式的依赖关系SmtpTransport
。换句话说,对于EmailSender
为了能够完成它的工作,它需要一个实例SmtpTransport
被注入其中。 (请注意,虽然EmailSender
有依赖性,SmtpTransport
才不是。)
说你需要使用EmailSender
位于应用程序的五个不同位置。在每个地方,您可能有这样的代码:
$emailSender = new EmailSender(new SmtpTransport());
$emailSender->send($email)
这并不是很多代码(因为EmailSender
只有一个依赖项),但是当您决定不使用 SMTP 时会发生什么EmailSender
应该使用传输类sendmail
?您必须编辑每个代码块才能更新它。
另一种方法是注册EmailSender
及其作为服务的依赖项。
注册看起来像这样:
// YourApp/YourBundle/Resources/config/services.yml
services:
smtp_transport:
class: YourApp\YourBundle\Email\SmtpTransport
email_sender:
class: YourApp\YourBundle\Email\EmailSender
arguments:
- @smtp_transport
现在,要使用它(从container
感知上下文):
$container->get('email_sender')->send($email);
请注意,实际使用该类发送电子邮件是多么简单和干净?当然,您必须先完成注册服务的工作,但这很简单,只需完成一次。
想象一下EmailSender
具有三个依赖项,而不是一个。使用服务时,您只需要修改服务注册,而无需更改您的实现代码(用于发送电子邮件的代码)。
简而言之,服务层充当类的中央存储库,这些类 a) 具有一个或多个依赖项 b) 需要在“全局”范围内使用。通过从以下位置获取这些服务类Dependency Injection Container
,您最终会得到更少的冗余代码和更简单的方法来进行广泛的更改。
我可能是错的,但我认为 Symfony2 是第一个实现依赖注入容器的 PHP 框架。因此,很多 PHP 开发人员可能不熟悉服务的概念。我绝对建议您确保完全理解它,因为您会发现它是一个非常强大的工具。另外,服务的概念绝不限于 Symfony2 甚至 PHP - 您将能够在各种框架和语言中利用这个概念。