Сервис Symfony 3.4 autowire

Разрабатываю мини-приложение на Symfony 3.4. Собираю процесс аутентификации с помощью Guard. Я создал класс LoginFormAuthenticator, который расширяет AbstractFormLoginAuthenticator.

Ошибка получения:

Не удается выполнить автоматическое подключение службы «app.security.login_form_authenticator»: аргумент «$ em» метода «AppBundle \ Security \ LoginFormAuthenticator :: __ construct ()» ссылается на класс «Doctrine \ ORM \ EntityManager», но такой службы не существует. Попробуйте изменить подсказку типа на один из его родительских: интерфейс «Doctrine \ ORM \ EntityManagerInterface» или интерфейс «Doctrine \ Common \ Persistence \ ObjectManager».

Мой код в моем классе аутентификации формы:

    <?php

namespace AppBundle\Security;


use AppBundle\Form\LoginForm;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;

class LoginFormAuthenticator extends AbstractFormLoginAuthenticator
{
    private $formFactory;
    private $em;
    private $router;

    public function __construct(FormFactoryInterface $formFactory, EntityManager $em, RouterInterface $router)
    {

        $this->formFactory = $formFactory;
        $this->em = $em;
        $this->router = $router;
    }

    public function getCredentials(Request $request)
    {
        $isLoginSubmit = $request->getPathInfo() == '/login' && $request->isMethod('POST');

        if(!$isLoginSubmit){
            return false;
        }

        $form = $this->formFactory->create(LoginForm::class);
        $form->handleRequest($request);

        $data = $form->getData();
        return $data;
    }

    public function getUser($credentials, UserProviderInterface $userProvider)
    {
        $username = $credentials['_username'];

        return $this->em->getRepository('AppBundle:User')
            ->findOneBy(['email' => $username]);
    }

    public function checkCredentials($credentials, UserInterface $user)
    {
        $password = $credentials['_password'];
        if($password == 'iliketurtles'){
            return true;
        }
        return false;
    }

    protected function getLoginUrl()
    {
        return $this->router->generate('security_login');
    }
}

Мой services.yml:

services:
# default configuration for services in *this* file
_defaults:
    # automatically injects dependencies in your services
    autowire: true
    # automatically registers your services as commands, event subscribers, etc.
    autoconfigure: true
    # this means you cannot fetch services directly from the container via $container->get()
    # if you need to do this, you can override this setting on individual services
    public: false

# makes classes in src/AppBundle available to be used as services
# this creates a service per class whose id is the fully-qualified class name
AppBundle\:
    resource: '../../src/AppBundle/*'
    # you can exclude directories or files
    # but if a service is unused, it's removed anyway
    exclude: '../../src/AppBundle/{Entity,Repository,Tests}'

# controllers are imported separately to make sure they're public
# and have a tag that allows actions to type-hint services
AppBundle\Controller\:
    resource: '../../src/AppBundle/Controller'
    public: true
    tags: ['controller.service_arguments']

# add more services, or override services that need manual wiring
# AppBundle\Service\ExampleService:
#     arguments:
#         $someArgument: 'some_value'

app.security.login_form_authenticator:
    class: AppBundle\Security\LoginFormAuthenticator
    autowire: true 

Я новичок в Symfony, поэтому извиняюсь, если я упускаю что-то очевидное.


person Behzad Lashkari    schedule 25.02.2018    source источник
comment
Измените EntityManager на EntityManagerInterface в своем конструкторе.   -  person Cerad    schedule 26.02.2018
comment
Идеально! Это сработало, спасибо!   -  person Behzad Lashkari    schedule 26.02.2018
comment
Рад помочь. Теперь, пока он еще свежий, найдите время, чтобы понять, почему он работает: symfony.com /doc/current/service_container/autowiring.html Вы не продвинетесь далеко с S4 без хотя бы базового понимания autowire и контейнера служб. И bin / console debug: container --show-private должен стать одним из ваших лучших друзей.   -  person Cerad    schedule 26.02.2018
comment
Я не понимаю, почему за этот вопрос проголосовали. Ответ упоминается в сообщении об ошибке: попробуйте изменить подсказку типа на один из его родителей: interface Doctrine \ ORM \ EntityManagerInterface   -  person Stephan Vierkant    schedule 27.06.2018
comment
Потому что нельзя просто доверять сообщениям об ошибках - сообществу с объяснениями для победы!   -  person Milen    schedule 10.03.2019


Ответы (2)


Как отметил @Cerad в комментариях, вам следует изменить EntityManager на EntityManagerInterface в своем конструкторе.

Измените строку

use Doctrine\ORM\EntityManager;

to

use Doctrine\ORM\EntityManagerInterface;

А также поменять строчку

public function __construct(FormFactoryInterface $formFactory, EntityManager $em, RouterInterface $router)

to

public function __construct(FormFactoryInterface $formFactory, EntityManagerInterface $em, RouterInterface $router)
person pagliuca    schedule 18.04.2019
comment
Ребята, на этот вопрос уже был дан ответ в комментариях, но я решил ответить на него по-настоящему, поэтому он перестает отображаться в поиске неотвеченных вопросов. - person pagliuca; 18.04.2019

Интерфейс Doctrine \ Common \ Persistence \ ObjectManager больше не имеет псевдонима для службы doctrine.orm.entity_manager, вместо этого используйте Doctrine \ ORM \ EntityManagerInterface.

person Alex - Exaland Concept    schedule 06.12.2019