[英]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.