Symfony 4.1组件 - 依赖注入问题

4

我正在重构使用 PHP 编写的旧应用程序。

我尝试使用 Symfony 依赖注入组件将服务注入控制器(或其他服务),但我不知道如何实现这一点,因为 Symfony 文档更适用于使用框架而不是框架组件。

我已经拥有自己的 Kernel、Container,其中包含所有服务和控制器(控制器已经作为服务注册)。我的控制器扩展了 symfony/frameworkbundle 中的 AbstractController。所以现在我能做的唯一一件事就是:

通过 $this->container->get('service_id') 从容器中获取服务,但如果构造函数中的服务需要类作为参数,则:

public function __constructor(SomeClass $someClass)

然后我遇到了这个异常:

当容器编译时,“App\V2\Service\TestService”服务或别名已被删除或内联。您应该将其公开,或停止直接使用容器并改用依赖注入。

如果我更改配置以使所有服务公开,则会出现以下情况:

APP\V2\Service\TestService::__construct()函数参数过少,需要传递1个参数,但只传递了0个参数

我准备了一个 gist,以便更好地了解我的问题: https://gist.github.com/miedzwin/49bac1cc1d5270d3ba1bfcf700abf864

有人能帮我使用Symfony组件(而不是Symfony框架)实现DI吗?一个良好的工作示例就足够了。或者请在我的gist中提出您的意见,我会尝试修复它。


1
另外,你可以像这样简化你的配置:https://gist.github.com/TomasVotruba/09af5a9452abaa91b64c15b740d74f2e/revisions#diff-445ee136220060a93c1410f85d1e7e15 - Tomas Votruba
1
@TomášVotruba 我没有注册服务,应该自动注册,因为 autowire: true。我更新了代码片段,你可以查看 TestService.php 的样子。 - miedzwin
1
好的,我已经按照你在gist中所做的更改进行了修改(ControllerResolver和ArgumentResolver现在应该是public的,否则我无法在Framework类中使用它们)。现在看起来更好了,但我现在有另一个问题:
  1. 如果在服务配置中默认为public: true,那么在构造函数中具有标量类型参数(字符串、整数、数组)的服务将无法自动装配。 Cannot autowire service "APP\V2\Service\API": argument "$facebookUserId" of method "__construct()" has no type-hint, you should configure its value explicitly.
- miedzwin
1
如果public: false - Controller "APP\V2\Controller\API\SocialNetworkController::loginAction()"需要您为"$testService"参数提供一个值。这可能是因为该参数可为空,但未提供空值,未提供默认值或者在此参数之后还有非可选参数。因此,看起来服务仍未注入。 - miedzwin
非常感谢您的反馈!您刚刚给了我重要的元素。我会尝试为您的情况撰写一个适当的答案。 - Tomas Votruba
显示剩余3条评论
2个回答

3

Symfony 4/5 自动装配方式

从您的问题和评论中,我认为您只需要修复自动装配即可。

Symfony 4 的方式很简单:尽可能地自动装配所有服务和参数,无需手动设置

为了适应您的示例,以下是最适合您需求和 Symfony 4 的配置:

services:
    _defaults:
        # pass service dependencies to constructors by default
        autowire: true

        # add known tags (for commands, event subscribers etc) by default
        autoconfigure: true
        
        # to make using tests, bin files and another simpler
        public: true

        # autowiring of string/array/int parameters to constructors
        # this fixes cases like "argument "$facebookUserId" of method "__construct()" has no type-hint, you should configure its value explicitly"
        bind:
            # $constructorVariableName: %parameter% in config
            $facebookUserId: '%facebook_user_id%'

    APP\V2\:
        resource: '../src/app/V2/*'
        exclude: '../src/app/V2/{Script, Trait}'

    # symfony services - you still have to setup 3rd paryt services manually
    Symfony\Component\DependencyInjection\ParameterBag\ContainerBag:
        arguments:
            - '@service_container'
    # ...

继续阅读的地方


-1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接