管理与父服务的公共依赖关系

编辑本页

警告:您正在浏览的文档欧宝体育电话欧宝娱乐app下载地址Symfony 2.4,现已不再维护。

本页的更新版本用于Sy欧宝娱乐app下载地址mfony 6.2(当前稳定版本)。

管理与父服务的公共依赖关系

当您向应用程序添加更多功能时,您很可能开始拥有共享一些相同依赖项的相关类。例如,你可能有一个Newsletter Manager欧宝app在哪里找,它使用setter注入来设置它的依赖项:

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
欧宝app在哪里找NewsletterManager受保护的梅勒受保护的emailFormatter公共函数setMailer(梅勒梅勒->梅勒=梅勒;}公共函数setEmailFormatter(EmailFormatteremailFormatter->emailFormatter =emailFormatter;}/ /……

还有一个Greeting Card类,它们有相同的依赖关系:

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
GreetingCardManager受保护的梅勒受保护的emailFormatter公共函数setMailer(梅勒梅勒->梅勒=梅勒;}公共函数setEmailFormatter(EmailFormatteremailFormatter->emailFormatter =emailFormatter;}/ /……

这些类的服务配置看起来像这样:

  • YAML
  • XML
  • PHP
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
参数:#……欧宝app在哪里找newsletter_manager.class:欧宝app在哪里找NewsletterManagergreeting_card_manager.class:GreetingCardManager服务:my_mailer:#……my_email_formatter:#……欧宝app在哪里找newsletter_manager:类:“%欧宝app在哪里找 newsletter_manager.class %”电话:-[setMailer,[" @my_mailer "]]-[setEmailFormatter,[" @my_email_formatter "]]greeting_card_manager:类:“% greeting_card_manager.class %”电话:-[setMailer,[" @my_mailer "]]-[setEmailFormatter,[" @my_email_formatter "]]

在类和配置中都有很多重复。这意味着,如果你改变,例如,梅勒EmailFormatter如果要通过构造函数注入类,则需要在两个地方更新配置。同样地,如果您需要对setter方法进行更改,则需要在两个类中都这样做。处理这些相关类的公共方法的典型方法是将它们提取到一个超类中:

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
摘要MailManager受保护的梅勒受保护的emailFormatter公共函数setMailer(梅勒梅勒->梅勒=梅勒;}公共函数setEmailFormatter(EmailFormatteremailFormatter->emailFormatter =emailFormatter;}/ /……

欧宝app在哪里找NewsletterManager而且GreetingCardManager然后可以扩展这个超类:

1 2 3 4
欧宝app在哪里找NewsletterManager扩展MailManager/ /……

和:

1 2 3 4
GreetingCardManager扩展MailManager/ /……

以类似的方式,Symfony服务容器还支持在配置中扩欧宝娱乐app下载地址展服务,因此您还可以通过为服务指定父服务来减少重复。

  • YAML
  • XML
  • PHP
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16
#……服务:#……mail_manager:文摘:真正的电话:-[setMailer,[" @my_mailer "]]-[setEmailFormatter,[" @my_email_formatter "]]欧宝app在哪里找newsletter_manager:类:“%欧宝app在哪里找 newsletter_manager.class %”家长:mail_managergreeting_card_manager:类:“% greeting_card_manager.class %”家长:mail_manager

在这种情况下,有一个Service意味着父服务的参数和方法调用应该用于子服务。具体来说,为父服务定义的setter方法将在子服务实例化时被调用。

请注意

如果你移除配置键,服务仍然会被实例化,当然它们仍然会扩展MailManager类。区别在于省略了配置键将意味着调用定义在mail_manager在实例化子服务时,将不执行服务。

谨慎

范围摘要而且标签属性总是取自子服务。

父服务是抽象的,因为它不应该直接从容器中检索或传递给另一个服务。它仅仅作为其他服务可以使用的“模板”而存在。这就是为什么它可以没有将导致非抽象服务引发异常的配置。

请注意

为了解析父依赖项,ContainerBuilder必须先编译。看到编译容器欲知详情。

提示

在所显示的示例中,共享相同配置的类也从PHP中的相同父类扩展而来。这完全没有必要。您只需将类似服务定义的公共部分提取到父服务中,而无需在PHP中扩展父类。

重写父依赖关系

有时,您可能希望重写仅为一个子服务的依赖项传入的类。幸运的是,通过为子服务添加方法调用配置,父类设置的依赖项将被重写。如果你需要传递一个不同的依赖欧宝app在哪里找NewsletterManager类,配置看起来像这样:

  • YAML
  • XML
  • PHP
12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20 21
#……服务:#……my_alternative_mailer:#……mail_manager:文摘:真正的电话:-[setMailer,[" @my_mailer "]]-[setEmailFormatter,[" @my_email_formatter "]]欧宝app在哪里找newsletter_manager:类:“%欧宝app在哪里找 newsletter_manager.class %”家长:mail_manager电话:-[setMailer,[" @my_alternative_mailer "]]greeting_card_manager:类:“% greeting_card_manager.class %”家长:mail_manager

GreetingCardManager将收到与以前相同的依赖项,但是欧宝app在哪里找NewsletterManager将会通过my_alternative_mailer而不是my_mailer服务。

谨慎

你不能重写方法调用。当您在子服务中定义新的方法调用时,它将被添加到当前配置的方法调用集中。这意味着当setter覆盖当前属性时,它可以完美地工作,但当setter将它附加到现有数据(例如一个addFilters ()方法)。在这种情况下,唯一的解决办法就是扩展父服务并配置服务,就像您在了解此功能之前所做的那样。

此工作,包括代码示例,是根据创作共用BY-SA 3.0许可证。