对于这个例子,我必须使用简单的类来演示对B的依赖性
class A{
}
class B{
public function __construct(A $a ){
}
}
使用Symfony创建一些服务定义并设置DI
test.Service.A:
class: A
test.Service.B:
class: B
arguments: ["@test.Service.A"]
这是按预期工作的。
现在有一些第三类没有通过构造函数args显式定义它的依赖性,而是使用普通的选项数组
class C{
private $b;
public function __construct( array $options = array() ){
if( isset($options['B']) && $options['B'] instanceof B){
$this->b = $options['B'];
}
}
}
创建此对象看起来像这样
$c = new C( array(
'B' => new B( new A() )
));
现在我想为yml
中的C创建一个服务定义parameters:
test.options.C:
B: test.Service.B
test.Service.C:
class: C
arguments: ["%test.options.C%"]
如何将 test.options.C.B 指向我的服务 test.Service.B ?
这样做有用吗?
parameters:
test.options.C:
B: "@test.Service.B"
答案 0 :(得分:2)
不,它不起作用,parameters
对服务一无所知。
您的解决方案可能是创建Factory
服务:
services:
test.Service.C:
class: C
factory: ['@factory.service', createC]
factory.service:
class: D
arguments: ["@test.Service.B"]
您的D
班级:
class D
{
public function __construct(B $bInstance)
{
$this->B = $bInstance;
}
public static function createC()
{
return new C(array('B' => $this->B));
}
}
检查doc以获取有关如何使用工厂创建服务的更多信息
答案 1 :(得分:1)
使用DependencyInjection组件进行三种类型的注射。通常,您只在构造函数中使用注入,因为DI组件可以确定这种方式,您正在传递正确的类。
请参阅:https://symfony.com/doc/current/service_container/injection_types.html
我认为让DI传递一系列依赖关系是不可能的(我甚至不认为在构造函数中列出它们有任何优势)所以最佳选择可能是使用setter injections。
您也可以使用工厂创建服务,请参阅https://symfony.com/doc/current/service_container/factories.html。
答案 2 :(得分:0)
您可以使用表达式语言注入定义为参数的服务,如下所示:
parameters:
test.options.C:
B: "test.Service.B"
services:
test.Service.A:
class: A
test.Service.B:
class: B
arguments: ["@test.Service.A"]
test.Service.C:
class: C
arguments: ["@=service(parameter('test.options.C'))"]
的文档中的详细信息