使用服务别名进行依赖注入 [英] Using service aliases for dependency injection

查看:496
本文介绍了使用服务别名进行依赖注入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序中,我有一个短信服务。这个服务是一个简单的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆