如何在没有实际注入的情况下访问Symfony 4中的依赖注入容器?

时间:2019-05-22 18:54:14

标签: symfony dependency-injection

我有一个用Symfony 4编写的项目(如果需要,可以更新到最新版本)。在这种情况下,我的情况与此类似:

有一个控制器可以将请求发送到外部系统。它遍历数据库中的记录,并为每一行发送一个请求。为此,有一个MagicApiConnector类连接到外部系统,并且对于每个请求都有一个XxxRequest类(例如FooRequestBarRequest等)。 / p>

所以,类似这样的东西:

foreach ( $allRows as $row ) {
    $request = new FooRequest($row['a'], $row['b']);
    $connector->send($request);
}

现在,为了完成所有参数填充操作,请求需要访问Symfony的DI中定义的服务。控制器本身既不知道也不关心此服务,但是请求需要它。

我的请求类别如何访问此服务?我不想将其设置为控制器的依赖项-我可以,但是似乎有点尴尬,因为控制器实际上并不关心它,只会通过它。这是请求的实现细节,我觉得它不应该让样板需求负担请求的用户。

那么,有时您需要以更大的利益为名做出牺牲,那么也许是其中一种情况?感觉就像我在“背叛”,没有掌握一些思想观念。


已添加:确定,详细的gory详细信息,无任何简化。

这一切都是在两个自制系统的情况下发生的。我们称它们为OldApp和NewApp。两者都是API,NewApp正在调用OldApp。这些API是简单的REST / JSON样式。 OldApp不是基于Symfony构建的(大多数甚至不使用框架),NewApp是。我的问题是关于NewApp。

OldApp API的身份验证采用三种不同的方式,并且在将来需要时可能会得到更多的应用(这还没有结束!)。不同的API调用使用不同的身份验证方法。有时即使是同一API调用也可以使用不同的方法(取决于调用它的人)。所有这些认证方法也是自制的。一个使用POST字段,另一个使用自定义HTTP标头,不记得第三个。

现在,已分发给许多用户的Android应用正在调用NewApp。 Android应用程序实际上同时使用NewApp和OldApp。当它调用NewApp时,它将传递带有OldApp身份验证数据的额外HTTP标头(方法1)。因此,NewApp可以模拟OldApp的Android应用程序用户。此外,NewApp还需要使用用户自己无法调用的OldApp特殊命令(特权问题)。因此,它对该命令使用了不同的身份验证机制(方法2)。该命令的参数存储在本地配置中(环境变量)。

在我之前,一位同事创建了APIConnectorAPICommand的方案,在其中您将连接器作为依赖项并根据需要创建命令实例。连接器实际上执行HTTP请求;这些命令告诉它哪些POST字段和要发送的标头。我希望保留这个方案。

但是现在不同的身份验证机制又如何适应呢?每个命令都应该能够将所需的内容传递给连接器。并且该机制应可用于多个命令。但是一个需要访问传入的请求,另一个需要访问配置参数。两者都不通过DI实例化。如何优雅地做到这一点?

1 个答案:

答案 0 :(得分:3)

这听起来像是工厂的工作。

function action(MyRequestFactory $requestFactory)
{
    foreach ( $allRows as $row ) {
        $request = $requestFactory->createFoo($row['a'], $row['b']);
        $connector->send($request);
    }

工厂本身是一种服务,并作为正常Symfony设计的一部分注入到控制器中。无论需要任何其他服务,都将注入工厂。反过来,工厂可以在创建请求时提供单个请求可能需要的任何服务。