管理与父服务的公共依赖关系
编辑本页警告:您正在浏览的文档欧宝体育电话欧宝娱乐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(EmailFormatter$emailFormatter){$这->emailFormatter =$emailFormatter;}/ /……}
还有一个Greeting Card类,它们有相同的依赖关系:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
类GreetingCardManager{受保护的$梅勒;受保护的$emailFormatter;公共函数setMailer(梅勒$梅勒){$这->梅勒=$梅勒;}公共函数setEmailFormatter(EmailFormatter$emailFormatter){$这->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(EmailFormatter$emailFormatter){$这->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 ()
方法)。在这种情况下,唯一的解决办法就是不扩展父服务并配置服务,就像您在了解此功能之前所做的那样。