【问题标题】:How to make all Symfony DI services public?如何公开所有 Symfony DI 服务?
【发布时间】:2021-12-23 17:45:30
【问题描述】:

在我们的集成测试中,我们需要获取/设置一些服务,因此需要将它们公开。

我们目前所做的是以这种方式配置每个此类服务:

App\Infrastructure\Mail\Transport\SenderInterface:
    public: '%services_are_public%'

而我们的test 环境是这样配置的:

parameters:
    services_are_public: true

有没有办法在给定的环境中默认公开所有服务?

【问题讨论】:

  • 您可以将 public: true 添加到 services.yaml 文件的 _defaults 部分。但是你真的应该问为什么你需要公开所有这些服务只是为了测试。您还应该查看特定于环境的 services.yaml 文件是如何加载的。不需要像 service_are_public 这样的参数。
  • 没有必要,因为 4.1 there is a way to fetch private services from the containertest 环境中。
  • @yivi 抱歉,还没有,希望这周!

标签: php symfony testing dependency-injection symfony5


【解决方案1】:

如果您使用Symfony\Bundle\FrameworkBundle\Test\WebTestCaseSymfony\Bundle\FrameworkBundle\Test\KernelTestCase(您可能应该使用它,用于功能/集成测试),则无需公开服务。

这些类包括一个简单的方法来获取能够直接获取私有服务的“特殊”容器:

$container = static::$container;

since Symfony 4.1 就是这种情况,并记录在 here


如果由于某种原因上述方法对您不起作用,您可以创建一个services_test.yaml 文件并添加以下内容:

# config/services_test.yaml

services:
    _defaults:
        public: true      

...但这只会影响自动装配的服务。如果您需要访问通过捆绑包连接的服务,该服务将保持私有。


最后,您可以创建一个编译器通道来公开所有服务:

class MakeServicesPublicPass implements CompilerPassInterface
{

    public function process(ContainerBuilder $container): void
    {
        foreach ($container->getDefinitions() as $id => $definition) {
            $definition->setPublic(true);
        }

        foreach ($container->getAliases() as $id => $alias) {
            $alias->setPublic(true);
        }
    }
}

...并仅在您的测试内核上注册此编译器传递。


就个人而言,如果可能的话,我会说第一个选项是你的方案。

【讨论】:

    猜你喜欢
    • 2017-06-03
    • 2019-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-30
    相关资源
    最近更新 更多