根据Symfony config

时间:2019-05-01 15:45:59

标签: php symfony dependency-injection symfony-3.4

假设我有一个接口ThingInterface和两个实现ThingMockThing。现在假设我正在使用依赖项注入并且已经针对ThingInterface进行了编程,那么在symfony中,我可以告诉它要使用哪种实现,如下所示:

services:
    ...
    ThingInterface: '@Thing'
    ...

是否可以根据参数选择和使用?例如:

parameters:
    useMock: 'true'

services:
    ...
    # ThingInterface maps to ThingMock or Thing based on useMock parameter
    ThingInterface: '@ThingMock'
    ...

我正在使用 symfony 3.4

这里的上下文是我将提供许多服务,并且我想轻松地在实际实现和模拟版本之间切换。我可以为每个服务单独执行此操作,但我希望可以通过参数“切换”来执行此操作。

我发现this给出了以下示例:

services:
    AppBundle\Mailer:
        arguments: ["@=container.hasParameter('some_param') ? parameter('some_param') : 'default_value'"]

但是我无法使其用于将接口映射到实现:

parameters:
    useMock: 'true'

services:
    ...
    # ThingInterface maps to ThingMock or Thing based on useMock parameter
    ThingInterface: '@ThingMock'
    ThingInterface: ["@=container.getParameter('useMock') ? service('ThingMock') : service('Thing')"]
    ...

1 个答案:

答案 0 :(得分:0)

由于某些未知的原因,仅将字符串设置为alias / remap的速记似乎根本不会用symfony求值。

您可以尝试以下方法:

Namespace\ClassA: ~
Namespace\ClassB: ~
Namespace\MyInterface:
    class: '%my_interface.class%'

但是,您可能最终得到该类的两个实例(两个服务)。不幸的是,别名似乎无效,也不会导入。

唯一的其他选择似乎很丑陋,并且基本上失去了自动装配,IE,到处绑定的功能。

不幸的是,这是唯一的实现方法,因为symfony不支持您的要求。

如果要执行此操作,则必须将其实现为框架扩展或使用其他框架。有很多github问题,并且拒绝了pull请求来确认这一点。