簡體   English   中英

Symfony 5.1 - 無法自動裝配服務

[英]Symfony 5.1 - Cannot autowire service

我想重構我的代碼,但現在我有錯誤並且不明白是什么。 Objectif:調用TokenService時不需要傳參數,使用自動裝配來自動裝配EntityManager & Request,controller調用服務時不要設置。

無法解析 App\Controller\TokenController::showTokens() 的參數 $tokenService 無法自動裝配服務 App\Service\TokenService 方法 __construct() 的參數 $request 引用 class Symfony\Component\HttpFoundation\Request 但不存在此類服務。

前:

/src/Controller/TokenController.php

<?php

namespace App\Controller;

use App\Service\TokenService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;

/**
 * @Route("/v1")
 */
class TokenController
{
   /** @var EntityManagerInterface $em */
    private $em;
    /** @var Request $request */
    private $request;

    /**
     * TokenService constructor.
     *
     * @param Request $request
     * @param EntityManagerInterface $em
     */
    public function __construct(Request $request, EntityManagerInterface $em)
    {
        $this->request = $request;
        $this->em = $em;
    }

    public function showTokens(Request $request, EntityManagerInterface $em): JsonResponse
    {
        $tokenService = new TokenService($request, $em);

        return $tokenService->getTokens();
    }
}

/src/Service/TokenService.php

<?php

namespace App\Service;

use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

/**
 * Class TokenService
 * @package App\Service
 */
class TokenService
{
    /** @var EntityManagerInterface $em */
    private $em;
    /** @var Request $request */
    private $request;

    /**
     * TokenService constructor.
     *
     * @param Request $request
     * @param EntityManagerInterface $em
     */
    public function __construct(Request $request, EntityManagerInterface $em)
    {
        $this->request = $request;
        $this->em = $em;
    }

    public function getTokens()
    {
        return true;
    }
}

后:

/config/services.yaml

parameters:

services:
    _defaults:
        autowire: true
        autoconfigure: true

    App\:
        resource: '../src/'
        exclude:
            - '../src/DependencyInjection/'
            - '../src/Entity/'
            - '../src/Kernel.php'
            - '../src/Tests/'

    App\Controller\:
        resource: '../src/Controller/'
        tags: ['controller.service_arguments']

    App\Service\TokenService: ~

/src/Controller/TokenController.php

<?php

namespace App\Controller;

use App\Service\TokenService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;

/**
 * @Route("/v1")
 */
class TokenController
{
    public function showTokens(Request $request, EntityManagerInterface $em, TokenService $tokenService): JsonResponse
    {
        return $tokenService->getTokens();
    }

/src/Service/TokenService.php

<?php

namespace App\Service;

use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
/**
 * Class TokenService
 * @package App\Service
 */
class TokenService
{
    /** @var EntityManagerInterface $em */
    private $em;
    /** @var Request $request */
    private $request;

    /**
     * TokenService constructor.
     *
     * @param Request $request
     * @param EntityManagerInterface $em
     */
    public function __construct(Request $request, EntityManagerInterface $em)
    {
        $this->request = $request;
        $this->em = $em;
    }

    public function getTokens()
    {
        return true;
    }
}

謝謝 !

我想我們已經有一段時間沒有提出很好的請求堆棧問題了。 我進行了一些搜索,但沒有找到任何直接適用並提供了體面解釋的答案。

基本問題是 Symfony 框架支持嵌套請求。 例如,當使用嵌入式控制器時,您會得到這些。 所以沒有實際的請求服務。 實際上曾經有過 Symfony 2.0 首次發布的時候,但它確實是一團糟。 支持嵌套請求服務是在容器級別完成的,並不好玩。

因此引入了稱為 請求堆棧的大錘子來一勞永逸地解決問題。 注入請求堆棧而不是請求,然后在您實際需要時訪問請求。

class TokenService
{
    private $em;
    private $requestStack;

    public function __construct(RequestStack $requestStack, EntityManagerInterface $em)
    {
        $this->requestStack = $requestStack;
        $this->em = $em;
    }

    public function getTokens()
    {
        $request = $this->requestStack->getMasterRequest(); // or possibly getCurrentRequest depending on where the tokens are
        return true;
    }

話雖如此,我個人只是通過 controller 的請求。 這樣做可以消除我的“取決於”評論。 我也認為它減少了一點所涉及的“魔法”。 這兩種方法都行得通。

class TokenService
{
    public function getTokens(Request $request)
    {
        return true;
    }
...
class TokenController
{
    public function showTokens(Request $request, TokenService $tokenService): JsonResponse
    {
        return $tokenService->getTokens($request);
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM