Symfony 4抽象父类依赖注入异常:仅部分依赖被注入
问题:Symfony抽象父类依赖注入不完整,仅部分依赖被正确注入
我有一个名为CommonService的抽象类,构造函数包含大量依赖项,该父类有3个子类。此前子类需要每次向父类构造函数传递这些依赖,我尝试通过配置让子类无需再提供父类依赖。
我按照官方文档在services.yaml中做了如下配置:
App\Service\Events\Common\CommonService: abstract: true arguments: - '@App\DTO\Common\Mapper\CommonEventListDTOMapper' - '@App\DTO\Common\Mapper\CommonProductProcessListOutOfAuditDTOMapper' - '@App\DTO\Common\Mapper\CommonProductProcessListDTOMapper' - '@App\DTO\Common\Mapper\CommonEventDTOMapper' - '@App\Repository\Events\OutAudit\EventProcessRepository' - '@App\Repository\Events\OutAudit\EventProductRepository' # 其他依赖... App\Service\Events\Audit\NcService: parent: App\Service\Events\Common\CommonService autowire: true autoconfigure: false App\Service\Events\OutAudit\ProcessService: parent: App\Service\Events\Common\CommonService autowire: true autoconfigure: false App\Service\Events\OutAudit\ProductService: parent: App\Service\Events\Common\CommonService autowire: true autoconfigure: false
该抽象类包含多个属性,但目前仅两个依赖项被正确注入:
CommonProductProcessListDTOMapper $commonProductProcessListDTOMapper, CommonEventDTOMapper $commonEventDTOMapper
CommonService的核心实现代码(构造函数部分):
abstract class CommonService implements EventsInterface { // 属性定义... public function __construct( EventProcessRepository $eventProcessRepository, EventProductRepository $eventProductRepository, HistoryService $historyService, EntityManagerInterface $em, UserRepository $userRepository, UserService $userService, TokenService $tokenService, SupplierService $supplierService, SupplierRepository $supplierRepository, OptionRepository $optionRepository, SmtpService $smtpService, ActionService $actionService, ActionRepository $actionRepository, BranchRepository $branchRepository, BranchService $branchService, AttachmentService $attachmentService, EventRcService $eventRcService, EventRepository $eventRepository, CommonEventListDTOMapper $commonEventListDTOMapper, CommonProductProcessListOutOfAuditDTOMapper $commonProductProcessListOutOfAuditDTOMapper, CommonProductProcessListDTOMapper $commonProductProcessListDTOMapper, CommonEventDTOMapper $commonEventDTOMapper ) { // 属性赋值... } }
问题原因分析
构造函数参数顺序不匹配
Symfony的arguments数组默认是按位置注入的,你在services.yaml中配置的依赖顺序和CommonService构造函数的参数顺序完全不一致。例如:yaml中第一个参数是CommonEventListDTOMapper,但构造函数第一个参数是EventProcessRepository,这会导致所有依赖都被错误注入,仅最后两个参数刚好和yaml的后几位匹配,所以看起来只有这两个是正确的。parent继承与autowire的冲突
子类配置了autowire: true,Symfony会尝试自动注入父类的构造函数参数,但同时又继承了父类的arguments配置,两者混合会导致注入逻辑混乱:自动注入可能覆盖了部分父类的配置,或者优先级问题导致部分依赖未被正确处理。
解决方案
方案一:修正参数顺序 + 关闭子类自动注入
- 严格匹配参数顺序:将
services.yaml中CommonService的arguments顺序调整为和构造函数参数完全一致,例如:
App\Service\Events\Common\CommonService: abstract: true arguments: - '@App\Repository\Events\OutAudit\EventProcessRepository' - '@App\Repository\Events\OutAudit\EventProductRepository' - '@App\Service\HistoryService' - '@Doctrine\ORM\EntityManagerInterface' # EntityManagerInterface的服务ID - '@App\Repository\UserRepository' # 依次列出所有剩余参数,顺序必须和构造函数完全一致
- 关闭子类的
autowire:子类只需要继承父类配置即可,不需要自动注入,避免冲突:
App\Service\Events\Audit\NcService: parent: App\Service\Events\Common\CommonService autowire: false # 改为false autoconfigure: false
方案二:使用按名称注入(推荐,更健壮)
按名称注入不需要关心参数顺序,直接通过参数名绑定服务ID,避免顺序错误:
App\Service\Events\Common\CommonService: abstract: true arguments: $eventProcessRepository: '@App\Repository\Events\OutAudit\EventProcessRepository' $eventProductRepository: '@App\Repository\Events\OutAudit\EventProductRepository' $historyService: '@App\Service\HistoryService' $em: '@Doctrine\ORM\EntityManagerInterface' $userRepository: '@App\Repository\UserRepository' # 依次为每个构造函数参数指定对应的服务ID
子类同样保持parent继承并关闭autowire,配置和方案一一致。
方案三:拆分依赖(优化代码结构)
CommonService的构造函数依赖过多,违反了单一职责原则,可将相关依赖封装成更小的聚合服务:
- 例如创建
EventDependencyService,封装EventProcessRepository、EventProductRepository等事件相关依赖; - 创建
MapperCollectionService,封装所有DTO Mapper类; - 这样可以大幅减少
CommonService的构造函数参数数量,提升代码可维护性。
验证步骤
- 清理Symfony缓存:执行
php bin/console cache:clear,确保新配置生效; - 检查服务依赖:执行
php bin/console debug:container App\Service\Events\Audit\NcService,查看服务的依赖列表,确认所有依赖都已正确注入。
内容的提问来源于stack exchange,提问作者naspy971
相关产品推荐
相关产品推荐

