【问题标题】:How to inject method result of a service as an argument for another service?如何将服务的方法结果作为另一个服务的参数注入?
【发布时间】:2016-03-16 08:54:10
【问题描述】:

我有一个 FooService 从另一个配置服务获取一些数据。

我有该配置服务,因为配置因请求数据而异。配置服务注入了RequestStack 并构建了相关的配置数组。

我的FooService 如下所示:

class Foo
{
    private $config;

    /**
     * @param Config $config
     */
    public function __construct(Config $config) {
        $this->config = $config->getData();
    }
}

然而,我宁愿只注入getData的方法调用结果,而不是注入服务,因为它更容易进行单元测试。我不需要模拟配置,我可以传递一个数组。

我当前的service.yml 的定义如下:

config:
    ...

foo:
    class: Kopernikus\LeBundle\Service\Foo
    arguments:
        - @config

我尝试通过以下方式更改我的 foo 定义,例如工厂方法:

foo:
    class: Kopernikus\LeBundle\Service\Foo
    arguments:
        - [@config, getData]

但这也注入了整个服务。

如何将服务的方法结果作为另一个服务的参数注入?

【问题讨论】:

    标签: php symfony dependency-injection


    【解决方案1】:

    您可以使用表达式语言 (New in Symfony 2.4) 实现此目的

    如文档here 中所述,您可以执行以下操作:

    config:
        ...
    
    foo:
        class: Kopernikus\LeBundle\Service\Foo
            arguments:    ["@=service('config').getData()"]
    

    希望有帮助

    【讨论】:

    • 这里的括号太多了,因为它们注入了一个数组的数组。只需"@=service('config').getData()" 就足够了。 =)
    • 自版本 3 起已移动 here
    【解决方案2】:

    您基本上是在要求一个依赖注入容器。您可以自己制作一个具有简单函数(例如)get() 的函数,该函数返回 Foo 的新实例?您可以将其定义为在每次调用 get() 时创建新对象,或者创建更多始终返回相同对象的单例(通过将其存储在私有静态变量中)。

    例如,

    <?php
    class FooContainer implements YourContainerInterface {
        public static function get() {
            // Config logic here
            return new Foo($config);
        }
    }
    

    【讨论】:

    • 听起来 OP 正在询问如何将方法调用的结果注入服务而不是服务本身——尽管我不清楚他们为什么要这样做,所以我可能是误解了问题。
    • @JeremyHarris 我已经更新了我为什么要这样做的用例。
    • 以这种方式传递函数的唯一方法是通过字符串,这实际上并不理想,因为您无法对其进行任何类型检查(不使用其他逻辑)。在 PHP 中执行此操作的适当方法是通过容器对象。
    • 我看不到这个 esp 的好处。与其他两个提供的答案相比。我也不明白为什么不能进行类型检查。 config 函数当前在依赖服务的构造函数中返回一个数组,我可以使用该类型提示(或者如果我更改为一个对象,请使用它的类类型提示)。您能否详细说明这种方法何时会带来好处?或者与其他答案相比,我没有看到什么好处?
    • 如果您有一个需要 DI 容器的类,以便它可以访问服务,您可以根据该特定 DI 容器或其父类/接口进行类型提示。其他示例使用各种形式的 PHP 魔法,将字符串用作参数,然后解析字符串并返回一个对象。这是浪费和缓慢的。传递返回服务的 DI 容器对象的性能明显更高。
    猜你喜欢
    • 2021-06-07
    • 1970-01-01
    • 2013-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-05
    • 2012-08-01
    相关资源
    最近更新 更多