Доступ к доктрине в рамках пользовательского сервиса в Symfony4 - PullRequest
0 голосов
/ 25 февраля 2019

Сознавая, что по сети есть много информации об этом, у меня все еще много проблем с тем, чтобы заставить это работать.

Я создал специальную службу:

<?php

namespace App\Service;

use Doctrine\ORM\EntityManagerInterface;
use App\Entity\AccommodationType;
use App\Entity\Night;

class AvailabilityChecks {

    private $em;

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

    public function nightAvailable(string $RoomCode, string $NightDate) {


        $GetRoom = $this->em->getDoctrine()->getRepository(AccommodationType::class)->findOneBy([
                'RoomCode' => $RoomCode
            ]);

        $RoomQnt = $GetRoom->getNightlyQnt();

        $GetNight = $this->em->getDoctrine()->getRepository(Night::class)->findOneBy([
                'RoomCode' => $RoomCode,
                'NightDate' => $NightDate
            ]);

        $NumberOfNights = $GetNight->count();

        if($NumberOfNights<$RoomQnt) {
            return true;
        }
        else {
            return false;
        }

    }


}

и поместил это в services.yaml:

AvailabilityChecks.service:
  class: App\Service\AvailabilityChecks
  arguments: ['@doctrine.orm.entity_manager']

Поэтому, когда я пытаюсь использовать это в моем контроллере, я получаю эту ошибку:

Too few arguments to function App\Service\AvailabilityChecks::__construct(), 0 passed in /mypath/src/Controller/BookController.php on line 40 and exactly 1 expected

Я просто не могувыяснить, почему он не вводит ORM-вещи в конструктор!Любая помощь с благодарностью

Ответы [ 4 ]

0 голосов
/ 25 февраля 2019

В Symfony 4 вам не нужно создавать его как сервисы.Это автоматически сейчас.Просто введите зависимости, что вам нужно в конструкторе.Убедитесь, что у вас есть свойство autowire с истинным значением в services.yml (по умолчанию)

Удалите это из services.yml:

AvailabilityChecks.service:
  class: App\Service\AvailabilityChecks
  arguments: ['@doctrine.orm.entity_manager']

Вам не нужен EntityManagerInterface, потому что вы не являетесьсохраняйте что-либо, так что вставляйте только репозитории.

<?php

namespace App\Service;

use App\Entity\AccommodationType;
use App\Entity\Night;
use App\Repository\AccommodationTypeRepository;
use App\Repository\NightRepository;

class AvailabilityChecks {

    private $accommodationTypeRepository;
    private $nightRepository

     public function __construct(
          AcommodationTypeRepository  $acommodationTypeRepository,
          NightRepository $nightRepository
    )
    {
        $this->acommodationTypeRepository = $acommodationTypeRepository;
        $this->nightRepository = $nightRepository;
    }

    public function nightAvailable(string $RoomCode, string $NightDate) {


        $GetRoom = $this->acommodationTypeRepository->findOneBy([
                'RoomCode' => $RoomCode
            ]);

        $RoomQnt = $GetRoom->getNightlyQnt();

        $GetNight = $this->nightRepository->findOneBy([
                'RoomCode' => $RoomCode,
                'NightDate' => $NightDate
            ]);

        $NumberOfNights = $GetNight->count();

        if($NumberOfNights<$RoomQnt) {
            return true;
        }
        else {
            return false;
        }

    }
}
0 голосов
/ 25 февраля 2019

В SF4 вам больше не нужно указывать зависимости, необходимые для вашей пользовательской службы, в файле service.yaml.Все, что вам нужно сделать, это использовать внедрение зависимостей.

Итак, удалите строки конфигурации и вызовите свой сервис напрямую в методе контроллера:

<?php

namespace App\Controller;

use App\Service\AvailabilityChecks ;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class AppController extends AbstractController
{
    public function index(AvailabilityChecks $service)
    {
        ...
    }
}

Сказав это, я думаю, вам не нужен специальный сервис для выполнения простых операций с базой данных.Вместо этого используйте репозиторий.

0 голосов
/ 25 февраля 2019

Проблема в вашем BookController.Даже если вы не опубликовали его код, я могу предположить, что вы создаете new AvailabilityChecks в нем (в строке 40).

В Symfony каждый сервис создается сервисным контейнером.Вы никогда не должны создавать объекты обслуживания самостоятельно.Вместо этого BookController должен запросить сервисный контейнер для услуги AvailabilityChecks.Как это должно быть сделано?

В Symfony <3.3 мы обычно использовали: </p>

use Symfony\Bundle\FrameworkBundle\Controller\Controller;


class MyController extends Controller 
{
    public function myAction() 
    {
        $em = $this->get('doctrine.orm.entity_manager');
        // ...
    }
}

В настоящее время сервисы могут быть внедрены в контроллеры с помощью autowiring , что намного проще:

use Doctrine\ORM\EntityManagerInterface;

class MyController extends Controller 
{
    public function myAction(EntityManagerInterface $em) 
    {
        // ...
    }
}
0 голосов
/ 25 февраля 2019

Вы используете неправильный сервис для того, что вы хотите сделать.Используемый псевдоним doctrine, например, в AbstractController при вызове getDoctrine(), привязан к службе Doctrine\Common\Persistence\ManagerRegistry.

Так что написанный вами код лучше подходит для этого, и вам следует либо добавить @doctrine или @Doctrine\Common\Persistence\ManagerRegistry к определению услуги.

Как с вашей текущей конфигурацией, так и с измененной, вам не нужно звонить $this->em->getDoctrine(), потому что $this->em уже эквивалентно $this->getDoctrine() от вашегоконтроллер.Вместо этого вы можете создать (приватный) метод, чтобы он выглядел больше как этот код, например:

private function getDoctrine()
{
    return $this->em;
}

Затем вы можете вызвать $this->getDoctrine()->getRepository(...) или напрямую использовать $this->em->getRepository(...).

...