Как внедрить Doctrine Entity Manager в сервис Symfony 4

У меня есть контроллер

use Doctrine\ORM\EntityManagerInterface:
class ExampleController{
   public function someFunction(ExampleService $injectedService){
       $injectedService->serviceFunction();
    }
}

С сервисом

use Doctrine\ORM\EntityManagerInterface;
class ExampleService{
    public function __construct(EntityManagerInterface $em){
        ...
    }    
}

Однако вызовы someFunction() завершаются ошибкой из-за того, что передается 0 параметров (EntityManagerInterface не внедряется). Я пытаюсь использовать EntityManager из службы. Авто проводка включена. Я пробовал решения для Symfony3, но они, похоже, не работают, если я чего-то не упускаю.

Обновлено: вот мой services.yaml:

services:
    _defaults:
        autowire: true
        autoconfigure: true
        public: false 

    App\:
        resource: '../src/*'
        exclude: '../src/{Entity,Migrations,Tests,Kernel.php}'

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

Ваш код должен работать с автоматическим подключением, можем ли мы увидеть ваш services.yaml

Smaïne 02.04.2018 23:30

@ Smaïne Да, добавила сейчас. Некоторые решения Symfony 2/3 имеют services: your.service.here: class: app\service\here arguments: [@doctrine.orm.entity_manager], но я не уверен на 100% в том, что я указал правильный сервис и класс обслуживания, или если это даже применимо к моему сценарию.

BLaZuRE 03.04.2018 03:33

Вы можете сообщить мне об ошибке, у меня такая же конфигурация, и она работает для меня

Smaïne 03.04.2018 09:26

если вы сами позвоните в someFunction(), вы обязаны предоставить введенную услугу .. Я ничего не могу сделать для вас.

Rufinus 04.04.2018 10:53

Вы когда-нибудь находили решение? У меня точно такая же проблема.

Rudy Broersma 26.06.2018 10:06
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Symfony Station Communiqué - 17 февраля 2023 г
Symfony Station Communiqué - 17 февраля 2023 г
Это коммюнике первоначально появилось на Symfony Station , вашем источнике передовых новостей Symfony, PHP и кибербезопасности.
Управление ответами api для исключений на Symfony с помощью KernelEvents
Управление ответами api для исключений на Symfony с помощью KernelEvents
Много раз при создании api нам нужно возвращать клиентам разные ответы в зависимости от возникшего исключения.
6
5
18 924
4

Ответы 4

Классический сервис Symfony с автоматическим подключением использует метод внедрения конструктора для внедрения зависимостей. В вашем случае у вас нет конструктора.

Вы можете добавить метод конструктора и установить зависимость для свойства частного класса. И используйте соответственно.

Или вы можете использовать сеттер инъекций.

Конфигурация услуги:

services:
 app.example_controller:
     class: Your\Namespace\ExampleController
     calls:
         - [setExampleService, ['@exampleService']]

Класс контроллера:

class ExampleController
{
    private $exampleService;

    public function someFunction() {
        $this->exampleService->serviceFunction();
    }

    public function setExampleService(ExampleService $exampleService) {
        $this->exampleService = $exampleService;
    }
}

Класс ExampleService содержит конструктор. Несмотря на отсутствие во фрагменте, у службы есть свойство em, а у конструктора - $this->em = $em. В документации указано: «Вы можете указать [аргумент в YAML]». Формулировка заставила меня подумать, что это необязательно. Действительно ли это требуется?

BLaZuRE 06.04.2018 08:28

Как выполнить метод класса ExampleController-> someFunction? Не могли бы вы представить контекст? Если вы выполняете этот метод вручную, вам необходимо передать зависимость. Это ожидаемое поведение.

Yarimadam 06.04.2018 09:19

Согласен с Яримадамом. Контейнер служб, внедрение зависимостей и автоматическое подключение - это не история о внедрении в методы. Зависимости, внедренные в объекты, которые мы называем «услугами».

Когда приложение запущено, создается сервисный контейнер, внедряющий одни сервисы в другие через конструктор класса или вызов метода «set».

Ваш ExampleController::someFunction предназначен для вызова только вами, поэтому единственный способ, которым этот метод получит $injectedService в качестве аргумента, - это то, что вы его явно передадите. Это неправильный путь.

Я знаю, что это старый пост, но на случай, если кто-то с этим не справится, в статусе использования есть опечатка:

use Doctrine\ORM\EntityManagerInterface: //<- see that's a colon, not a semicolon

Используйте только в Symfony 4.

use Doctrine\ORM\EntityManagerInterface;
use App\Entity\Name; //if you use entity for example Name

class ExampleService{
    private $em;
    public function __construct(EntityManagerInterface $em)
    {
        $this->em = $em;
    }

    function newName($code) // for example with a entity
    {
        $name = new Name();
        $name->setCode($code); // use setter for entity

        $this->em->persist($name);
        $this->em->flush();
    }
}

Но выдает ошибку: MyService::__construct() must implement interface Doctrine\ORM\EntityManagerInterface, string given

TangMonk 12.08.2019 16:23

Другие вопросы по теме