使用服务别名进行依赖注入 [英] Using service aliases for dependency injection
问题描述
在我的应用程序中,我有一个短信服务。这个服务是一个简单的POPO,它为驱动程序提供一个实例来执行实际的SMS功能。
In my application I have an SMS service. This service is a simple POPO that takes an instance to a driver to do the actual SMS functionality.
想象一下,我有两个驱动程序, mock_driver
和
gateway_driver
在服务中定义为这样的东西
部分:
Imagine I have two drivers, mock_driver
and gateway_driver
which are defined as something like this in the services
section:
mock_driver:
class: MyApp\Service\Sms\MockDriver
gateway_driver:
class: MyApp\Service\Sms\GatewayDriver
calls:
- [setConfig, ["%gateway_user%", "%gateway_password%", "%gateway_endpoint%"]]
SMS服务的定义如下:
And the SMS service is defined like this:
service_sms:
class: MyApp\Service\SmsService
calls:
- [setDriver, ["%service_sms_driver%"]]
我所面临的问题是我要将两个驱动程序之一的实例传递到 setDriver
我的服务方法。应该在我的 parameters.yml
中定义哪个驱动程序,例如:
The problem I'm facing is that I want to pass an "instance" of one of the two drivers into the setDriver
method of my service. Which driver this is should be defined in my parameters.yml
, something such as:
service_sms_driver: ["@mock_driver"]
但是,我被困在语法上使其正常工作。我认为它的要点是正确的,除了我的 parameters.yml
中的 service_sms_driver
值的语法, code> setDriver 方法调用实际的服务。
However, I'm stuck on the syntax to make this work correctly. I think the gist of it is correct except for the syntax on the service_sms_driver
value in my parameters.yml
and the setDriver
method call on the actual service.
任何帮助赞赏。
编辑:
作为一个澄清,两个驱动程序实现相同的界面。但是,每个驱动程序可能需要不同的配置方式,这些方法可能无法在接口中捕获。如果我只是传递类名称,它可以正常工作,但我试图注入实例。希望这是有道理的。
Just as a clarification, both drivers implement the same interface. However, every driver might need different ways of configuration which might not be captured in an interface. If I was simply passing class names it would work fine but I'm trying to inject instances instead. Hope this makes sense.
推荐答案
由于您的服务构造不同,别名似乎是一个正确的想法。
为此,只需创建两个驱动程序服务和您的经理。 (请注意使用 @driver
)
Since your services construct differently, the idea of aliasing seems to be a correct idea.
To do so, just create your two driver services and your manager. (Note the usage of @driver
)
服务.yml
gateway_driver:
class: Acme\FooBundle\GatewayDriver
mock_driver:
class: Acme\FooBundle\MockDriver
manager:
class: Acme\FooBundle\SmsManager
arguments: [ @driver ]
然后,您可以将此别名编辑到您的 AcmeFooExtension
文件
Then, you can edit this alias into your AcmeFooExtension
file
Acme / FooBundle / DependencyInjection / AcmeFooExtension.php
public function load(array $configs, ContainerBuilder $container)
{
$driver = $container->getParameter('service_sms_driver');
$container->setAlias('driver', $driver);
}
这将采取 service_sms_driver
参数并创建此服务的别名。
This will take the service_sms_driver
parameter and create an alias of this service.
调试示例:
config_dev.yml
parameters:
service_sms_driver: mock_driver
运行
$ php app/console --env=dev container:debug driver
结果
[container]服务驱动程序的信息
此服务是服务mock_driver的别名
[container] Information for service driver
This service is an alias for the service mock_driver
config_prod.yml >
parameters:
service_sms_driver: gateway_driver
运行
$ php app/console --env=prod container:debug driver
结果
[container]服务驱动程序的信息
此服务是服务gateway_driver的别名
[container] Information for service driver
This service is an alias for the service gateway_driver
config_test.yml
parameters:
service_sms_driver: unknown_driver
运行
$ php app/console --env=test container:debug driver
结果
[Symfony\Component\DependencyInjection \Exception\InvalidArgumentException]
服务定义unknown_driver不存在。
[Symfony\Component\DependencyInjection\Exception\InvalidArgumentException]
The service definition "unknown_driver" does not exist.
这篇关于使用服务别名进行依赖注入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!