在Symfony4中的自定义服务中访问Doctrine

问题描述 投票:0回答:4

意识到网络上有很多关于此的信息,我仍然很难让这个工作。

我创建了一个自定义服务:

<?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东西注入构造函数中!任何帮助非常感谢

symfony orm doctrine-orm doctrine symfony-4.2
4个回答
1
投票

问题在于你的BookController。即使您没有发布其代码,我也可以假设您在其中创建了new AvailabilityChecks(第40行)。

在Symfony中,每个服务都由服务容器实例化。您永远不应该自己实例化服务对象。相反,BookController必须向服务容器询问AvailabilityChecks服务。应该怎么做?

在Symfony <3.3中,我们通常使用:

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
投票

您正在使用错误的服务来执行您想要的操作。使用的别名doctrine,例如在您调用getDoctrine()时,在AbstractController中绑定服务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(...)


0
投票

在Symfony 4中,您不需要将其创建为服务。这是自动的。只需在构造函数中注入所需的依赖项。确保您在services.yml中具有true值的autowire属性(默认情况下)

从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
投票

在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)
    {
        ...
    }
}

话虽如此,我认为你不需要自定义服务来对数据库进行简单的操作。请改用存储库。

© www.soinside.com 2019 - 2024. All rights reserved.