Я хочу рефакторить свой код, но теперь у меня ошибка, и я не понимаю, что. Objectif : не нужно передавать параметры при вызове TokenService и использовать автоматическое подключение для автоматического подключения EntityManager & Request и не устанавливать его при вызове службы контроллера.
Не удается разрешить аргумент $tokenService для App\Controller\TokenController::showTokens() Не удается выполнить автоподключение службы App\Service\TokenService аргумент $request метода __construct() ссылается на класс Symfony\Component\HttpFoundation\Request, но такой службы не существует.
До :
/src/Контроллер/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/Сервис/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/Контроллер/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/Сервис/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;
}
}
Спасибо !
Это для примера! Запрос используется после обслуживания, у меня есть простой код, чтобы не усложнять ситуацию. У меня есть запись objectif и ошибка
Признаюсь, я понятия не имею, о чем говорит ваш комментарий. Сообщение об ошибке говорит вам, где именно проблема. Ссылка, которую я разместил, говорит вам, как это исправить.
Я думаю, мы не понимаем друг друга. Я могу очень хорошо получить запрос в службе, так как он передается в качестве аргумента при создании экземпляра в контроллере. За исключением того, что я считаю бесполезным в контроллере, для всех вызовов, сделанных в эту службу, систематически предоставлять Request/EntityManager, поэтому я хочу пройти через внедрение зависимостей, чтобы оба можно было использовать из службы, не имея предоставить их во время создания экземпляра.
Вы правы в том, что мы явно не понимаем друг друга. Что хорошо. Может быть, кто-то еще придет. Но мне очень любопытно, как вы думаете, что сообщение об ошибке: «Не удается автоматически подключить сервис App\Service\TokenService аргумент $request метода __construct()» означает, что вы успешно внедрили службу запроса? Тем более, что нет службы запросов. Ваш контроллер, конечно же, должен выполнять return $tokenService->getTokens($request); но это почти не имеет значения.
Возможно, это поможет: symfony.com/blog/new-in-symfony-2-4-the-request-stack
Хорошо, я понял свою ошибку! Я использовал ваш ответ, и он отлично работает. Используйте RequestStack и удалите все «аргументы запроса» в контроллере, и служба будет нормально работать с autowire! Вы можете использовать его (и документы) на ответе, и я поддерживаю вас, чтобы решить эту проблему! Спасибо






Я думаю, прошло некоторое время с тех пор, как у нас был хороший вопрос о стеке запросов. Я немного поискал и не нашел ответа, который был бы непосредственно применим и дал достойное объяснение.
Основная проблема заключается в том, что среда 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);
}