php - Symfony 5.1 - 无法自动装配服务
问题描述
我想重构我的代码,但现在我有错误并且不明白是什么。Objectif :调用 TokenService 时不需要传递参数,使用自动装配来自动装配 EntityManager & Request,控制器调用服务时不要设置。
无法解析 App\Controller\TokenController::showTokens() 的参数 $tokenService 无法自动装配服务 App\Service\TokenService 方法 __construct() 的参数 $request 引用类 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;
}
话虽如此,我个人只会传递控制器的请求。这样做可以消除我的“取决于”评论。我也认为它减少了一点所涉及的“魔法”。这两种方法都行得通。
class TokenService
{
public function getTokens(Request $request)
{
return true;
}
...
class TokenController
{
public function showTokens(Request $request, TokenService $tokenService): JsonResponse
{
return $tokenService->getTokens($request);
}
推荐阅读
- python - Pandas Python Not found 模块 - Azure devops Flask App CI/CD 管道
- swiftui - 如何在 SwiftUI 上为 PageTabViewStyle 添加阴影?
- android - 如何正确遍历 ZipInputStream 的所有条目?
- mysql - 子查询的一般混淆
- javascript - 全屏 API 在 Chrome 中突然停止工作
- shell - Raspberrypi Python 代码无法正常工作
- java - 通过 JSP 循环访问 ENUM 值
- google-apps-script - 记录仪输出时间显示
- vue.js - Nuxt + Vuetify 无法读取 null 的属性“电子邮件”
- java - 在 JavaFX 的 for 循环中放置形状时出错