如何管理与父服务的共同依赖关系
编辑本页警告:您正在浏览的文档欧宝体育电话欧宝娱乐app下载地址Symfony 3.3,现已不再维护。
读本页的更新版本用于Sy欧宝娱乐app下载地址mfony 6.2(当前稳定版本)。
如何管理与父服务的共同依赖关系
当您向应用程序添加更多功能时,您很可能开始拥有共享一些相同依赖项的相关类。例如,您可能有多个存储库类需要doctrine.orm.entity_manager
服务和可选的日志记录器
服务:
12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20 21
/ / src / AppBundle /仓库/ BaseDoctrineRepository.php名称空间AppBundle\存储库;/ /……摘要类BaseDoctrineRepository{受保护的$entityManager;受保护的$日志记录器;公共函数__construct(EntityManagerInterface$经理){$这->entityManager =$经理;}公共函数setLogger(LoggerInterface$日志记录器){$这->记录器=$日志记录器;}/ /……}
您的儿童服务课程可能是这样的:
12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20 21
/ / src / AppBundle /仓库/ DoctrineUserRepository.php名称空间AppBundle\存储库;使用AppBundle\存储库\BaseDoctrineRepository/ /……类DoctrineUserRepository扩展BaseDoctrineRepository{//…} / /src/AppBundle/存储库/DoctrinePostRepository.php名称空间AppBundle\存储库;使用AppBundle\存储库\BaseDoctrineRepository/ /……类DoctrinePostRepository扩展BaseDoctrineRepository{//…}
就像你使用PHP继承来避免PHP代码中的重复一样,服务容器允许你扩展父服务以避免重复的服务定义:
- YAML
- XML
- PHP
12 3 4 5 6 7 8 9 10 11 12 13 14 15
服务:AppBundle \ Repository \ BaseDoctrineRepository:文摘:真正的参数:(“@doctrine.orm.entity_manager”)电话:-[setLogger,(' @logger '])AppBundle \ Repository \ DoctrineUserRepository:扩展AppBundle\Repository\ basedoctrinrepository服务家长:AppBundle \ Repository \ BaseDoctrineRepositoryAppBundle \ Repository \ DoctrinePostRepository:家长:AppBundle \ Repository \ BaseDoctrineRepository#……
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
<??> . xml version="1.0" encoding="UTF-8"<容器xmlns=“http://欧宝娱乐app下载地址www.oldmanjams.com/schema/dic/services”xmlns: xsi=“http://www.w3.org/2001/XMLSchema-instance”xsi: schemaLocation=“http://欧宝娱乐app下载地址www.oldmanjams.com/schema/dic/services //www.oldmanjams.com/schema/dic/services/services-1.0.xsd”><服务><服务id=“AppBundle \ Repository \ BaseDoctrineRepository”摘要=“真正的”><论点类型=“服务”id=“doctrine.orm.entity_manager”/><调用方法=“setLogger”><论点类型=“服务”id=“日志”/>调用>服务><!--扩展the AppBundle\Repository\BaseDoctrineRepository service --><服务id=“AppBundle \ Repository \ DoctrineUserRepository”父=“AppBundle \ Repository \ BaseDoctrineRepository”/><服务id=“AppBundle \ Repository \ DoctrinePostRepository”父=“AppBundle \ Repository \ BaseDoctrineRepository”/><!--...-->服务>容器>
12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20 21 22
使用AppBundle\存储库\DoctrineUserRepository;使用AppBundle\存储库\DoctrinePostRepository;使用AppBundle\存储库\BaseDoctrineRepository;使用欧宝娱乐app下载地址\组件\DependencyInjection\ChildDefinition;使用欧宝娱乐app下载地址\组件\DependencyInjection\参考;$容器->注册(BaseDoctrineRepository::类)->setAbstract (真正的)->addArgument (新引用(“doctrine.orm.entity_manager”))->addMethodCall (“setLogger”,数组(新引用(“日志”)));//扩展AppBundle\Repository\ basedoctrinrepository服务$定义=新ChildDefinition (BaseDoctrineRepository::类);$定义->setClass (DoctrineUserRepository::类);$容器->setDefinition (DoctrineUserRepository::类,$定义);$定义=新ChildDefinition (BaseDoctrineRepository::类);$定义->setClass (DoctrinePostRepository::类);$容器->setDefinition (DoctrinePostRepository::类,$定义);/ /……
在这种情况下,有一个父
Service意味着父服务的参数和方法调用应该用于子服务。具体来说,EntityManager
将被注入setLogger ()
将被调用,当AppBundle \ Repository \ DoctrineUserRepository
被实例化。
父服务上的所有属性都与子服务共享除了为共享
,摘要
和标签
.这些都是不继承自父类。
请注意
如果你有_defaults
节中,所有子服务都需要显式覆盖这些值以避免歧义。您将看到一条明确的错误消息。
提示
在所显示的示例中,共享相同配置的类也从PHP中的相同父类扩展而来。这完全没有必要。您只需将类似服务定义的公共部分提取到父服务中,而无需在PHP中扩展父类。
重写父依赖关系
有时您可能想要重写仅为一个子服务注入的服务。你可以通过简单地在子类中指定它来覆盖大多数设置:
- YAML
- XML
- PHP
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
服务:#……AppBundle \ Repository \ DoctrineUserRepository:家长:AppBundle \ Repository \ BaseDoctrineRepository#覆盖父服务的公共设置公众:假#追加@应用程序。使用rname_checker' argument to the parent#参数列表参数:(“@app.username_checker”)AppBundle \ Repository \ DoctrinePostRepository:家长:AppBundle \ Repository \ BaseDoctrineRepository#覆盖第一个参数(使用特殊的index_N键)参数:index_0:“@doctrine.custom_entity_manager”
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
<??> . xml version="1.0" encoding="UTF-8"<容器xmlns=“http://欧宝娱乐app下载地址www.oldmanjams.com/schema/dic/services”xmlns: xsi=“http://www.w3.org/2001/XMLSchema-instance”xsi: schemaLocation=“http://欧宝娱乐app下载地址www.oldmanjams.com/schema/dic/services //www.oldmanjams.com/schema/dic/services/services-1.0.xsd”><服务><!--...--><!--overrides the public setting of the parent service --><服务id=“AppBundle \ Repository \ DoctrineUserRepository”父=“AppBundle \ Repository \ BaseDoctrineRepository”公共=“假”><!--appends the '@app.username_checker' argument to the parent argument list --><论点类型=“服务”id=“app.username_checker”/>服务><服务id=“AppBundle \ Repository \ DoctrinePostRepository”父=“AppBundle \ Repository \ BaseDoctrineRepository”><!--overrides the first argument (using the index attribute) --><论点指数=“0”类型=“服务”id=“doctrine.custom_entity_manager”/>服务><!--...-->服务>容器>
12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20
使用AppBundle\存储库\DoctrineUserRepository;使用AppBundle\存储库\DoctrinePostRepository;使用AppBundle\存储库\BaseDoctrineRepository;使用欧宝娱乐app下载地址\组件\DependencyInjection\ChildDefinition;使用欧宝娱乐app下载地址\组件\DependencyInjection\参考;/ /……$定义=新ChildDefinition (BaseDoctrineRepository::类);$定义->setClass (DoctrineUserRepository::类);//覆盖父服务的公共设置$定义->setPublic (假);//添加'@app. '使用rname_checker' argument to the parent argument list$定义->addArgument (新引用(“app.username_checker”));$容器->setDefinition (DoctrineUserRepository::类,$定义);$定义=新ChildDefinition (BaseDoctrineRepository::类);$定义->setClass (DoctrinePostRepository::类);//覆盖第一个参数$定义->replaceArgument (0,新引用(“doctrine.custom_entity_manager”));$容器->setDefinition (DoctrinePostRepository::类,$定义);
此工作,包括代码示例,是根据创作共用BY-SA 3.0许可证。