如何为PSR-0规范的库实现依赖注入?Symfony3.4 DI配置报错求助
问题1:Symfony 3.4 service.yml配置错误修复
先看你贴出的配置代码,有一个非常明显的YAML语法错误:
AppBundle\Providers\BuilderInterface: class: AppBundle\Providers\Builder arguments: $service: '@Google_Service_Bigquery' $job: '@Google_Service_Bigquery_Job' $jobConfExtract: @Google_Service_Bigquery_JobConfigurationExtract' # 这里缺失了开头的单引号! $jobConf: '@Google_Service_Bigquery_JobConfiguration'
把@Google_Service_Bigquery_JobConfigurationExtract'修改为'@Google_Service_Bigquery_JobConfigurationExtract',补上开头的单引号,这是YAML语法的基础要求,缺失会导致容器解析配置失败。
接下来看错误提示里的Cannot autowire service,这说明你的Symfony 3.4项目开启了自动装配(autowire),但Google_Service_Bigquery这类PSR-0规范的第三方类并没有被注册为容器服务。Symfony的自动装配只能识别容器中已定义的服务,或是无构造函数、可直接实例化的类。
这里给你两种解决思路:
- 方案一:手动注册第三方类为容器服务
在service.yml中添加这些Google服务类的定义:
Google_Service_Bigquery: class: Google_Service_Bigquery arguments: ['@Google_Client'] # 假设你已配置好Google_Client服务 Google_Service_Bigquery_Job: class: Google_Service_Bigquery_Job # 若该类构造函数需要参数,需对应配置 Google_Service_Bigquery_JobConfigurationExtract: class: Google_Service_Bigquery_JobConfigurationExtract Google_Service_Bigquery_JobConfiguration: class: Google_Service_Bigquery_JobConfiguration
注册完成后,容器就能识别这些服务ID,你的Builder类参数注入就能正常工作。
- 方案二:关闭Builder类的自动装配
如果你不想注册这些第三方类,可以在Builder的服务定义中关闭autowire:
AppBundle\Providers\BuilderInterface: class: AppBundle\Providers\Builder autowire: false # 关闭自动装配 arguments: $service: '@Google_Service_Bigquery' $job: '@Google_Service_Bigquery_Job' $jobConfExtract: '@Google_Service_Bigquery_JobConfigurationExtract' $jobConf: '@Google_Service_Bigquery_JobConfiguration'
这种方式需要确保所有依赖都已手动配置好对应参数。
问题2:为PSR-0规范的库使用依赖注入
PSR-0本质是类自动加载规范,它定义了类名与文件路径的映射规则,和依赖注入本身没有冲突,只需确保这些类能被容器正确管理即可,步骤如下:
- 确保库已正确安装并配置自动加载
PSR-0规范的库通常可通过Composer安装,Composer会自动处理其自动加载规则(生成在vendor/composer/autoload_psr0.php中)。如果是自研的PSR-0库,需要在composer.json中配置psr-0字段:
{ "autoload": { "psr-0": { "YourLibraryNamespace": "src/" } } }
配置完成后执行composer dump-autoload更新自动加载文件。
- 将PSR-0库的类注册为容器服务
和前面Google服务的处理逻辑一致,Symfony依赖注入容器只能管理已注册的服务。对于PSR-0库中的类,你需要在service.yml(或xml/php配置文件)中手动定义服务:
YourLibraryNamespace\SomeClass: class: YourLibraryNamespace\SomeClass arguments: ['@some_dependency_service'] # 若类有构造函数依赖,需配置对应服务
- 在业务代码中注入使用
无论是控制器、其他服务还是命令类,都可以通过构造函数注入或setter注入的方式使用这些服务:
use YourLibraryNamespace\SomeClass; class YourService { private $someClass; public function __construct(SomeClass $someClass) { $this->someClass = $someClass; } }
只要你已在容器中注册了SomeClass的服务,Symfony就能自动注入(开启autowire的情况下),或是你手动在服务定义中配置参数。
- 额外注意事项
- 部分PSR-0库的类可能使用全局静态方法或单例模式,这种情况下建议封装一层服务类,将静态调用转为可注入的服务,避免代码紧耦合。
- 如果库的类构造函数需要复杂参数(比如API密钥、配置数组),可以在服务定义中通过
arguments配置,或是使用工厂服务来创建实例。
内容的提问来源于stack exchange,提问作者Artem Chernov
相关产品推荐
相关产品推荐

