서비스의 Symfony 2 EntityManager 삽입


96

내 자신의 서비스를 만들었고 EntityManager 교리를 주입해야하지만 __construct()내 서비스에서 호출되는 것을 볼 수없고 주입이 작동하지 않습니다.

다음은 코드와 구성입니다.

<?php

namespace Test\CommonBundle\Services;
use Doctrine\ORM\EntityManager;

class UserService {

    /**
     *
     * @var EntityManager 
     */
    protected $em;

    public function __constructor(EntityManager $entityManager)
    {
        var_dump($entityManager);
        exit(); // I've never saw it happen, looks like constructor never called
        $this->em = $entityManager;
    }

    public function getUser($userId){
       var_dump($this->em ); // outputs null  
    }

}

여기 services.yml내 번들에 있습니다

services:
  test.common.userservice:
    class:  Test\CommonBundle\Services\UserService
    arguments: 
        entityManager: "@doctrine.orm.entity_manager"

config.yml내 앱에서 .yml을 가져 왔습니다.

imports:
    # a few lines skipped, not relevant here, i think
    - { resource: "@TestCommonBundle/Resources/config/services.yml" }

컨트롤러에서 서비스를 호출하면

    $userservice = $this->get('test.common.userservice');
    $userservice->getUser(123);

나는 객체 (null이 아님)를 얻었지만 $this->emUserService에서 null이고 이미 언급했듯이 UserService의 생성자가 호출되지 않았습니다.

한 가지 더, Controller와 UserService는 서로 다른 번들에 있지만 (정말로 프로젝트를 구성하는 데 필요합니다) 다른 모든 것이 잘 작동하며 전화를 걸 수도 있습니다.

$this->get('doctrine.orm.entity_manager')

UserService를 가져오고 유효한 (null이 아님) EntityManager 개체를 가져 오는 데 사용하는 동일한 컨트롤러에서.

UserService와 Doctrine 구성 사이의 구성 또는 일부 링크가 누락 된 것 같습니다.


세터 주입을 시도해 보셨습니까? 효과가있다?
gremo

'setter injection'으로 내 서비스에 EntityManager에 대한 setter 메서드를 추가하고 매개 변수로 $ this-> get ( 'doctrine.orm.entity_manager')를 사용하여 컨트롤러에서 호출하면 예, 시도해 보았고 작동합니다. 하지만 구성을 통해 적절한 주입을 사용하고 싶습니다
Andrey Zavarin

2
내 말은 : symfony.com/doc/current/book/… 어쨌든 __constructor오류입니다.
gremo

음, 세터 주입을 시도하지 않은 것보다. __construct가 문제를 해결했지만 어쨌든 도움을 주셔서 감사합니다!
Andrey Zavarin

답변:


112

귀하의 클래스의 생성자 메서드를 호출해야 __construct()하지 __constructor():

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

2
안녕하세요,이 예에서 연결을 기본값에서 다른 것으로 어떻게 변경할 수 있습니까?
ptmr.io

맞습니다.하지만 인터페이스를 사용하면 더 좋을 것입니다. public function __construct(EntityManagerInterface $entityManager)
Hugues D

65

최신 참조를 위해 Symfony 2.4 이상에서는 Constructor Injection 메서드의 인수 이름을 더 이상 지정할 수 없습니다. 문서 에 따르면 다음을 전달합니다.

services:
    test.common.userservice:
        class:  Test\CommonBundle\Services\UserService
        arguments: [ "@doctrine.orm.entity_manager" ]

그런 다음 인수를 통해 나열된 순서대로 사용할 수 있습니다 (1 개 이상인 경우).

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

8
다음을 수행 할 수 있습니다. app / console container : debug 또한 실행중인 서비스를 찾습니다.
Hard Fitness

18

참고로 Symfony 3.3 EntityManager는 감가 상각됩니다. 대신 EntityManagerInterface를 사용하십시오.

namespace AppBundle\Service;

use Doctrine\ORM\EntityManagerInterface;

class Someclass {
    protected $em;

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

    public function somefunction() {
        $em = $this->em;
        ...
    }
}

1
누군가이 문제를 발견하고 혼란스러워하는 경우를 대비하여 EntityManager는 확실히 감가 상각되지 않았습니다. 인터페이스 사용은 자동 배선에 도움이되며 권장되지만 반드시 필요한 것은 아닙니다. 그리고 인터페이스는 오랫동안 사용되었습니다. 여기에 정말 새로운 것은 없습니다.
Cerad

이것이 답입니다. 그러나 참조하십시오 : stackoverflow.com/questions/22154558/…
tfont

내 솔루션으로 업데이트하십시오. 이제 올바른 방법은 엔터티와 리포지토리를 사용하는 것입니다. 엔티티 관리자는 이미 자연스럽게 저장소에 주입되었습니다. 여기에서 예를 볼 수 있습니다. youtu.be/AHVtOJDTx0M
Robert Saylor

7

2017 년부터 Symfony 3.3부터 Repository를 서비스로 등록 할 수 있으며 모든 장점이 있습니다.

더 일반적인 설명 내 게시물 How to use Repository with Doctrine as Service in Symfony확인하십시오 .


특정 경우에 튜닝이 포함 된 원본 코드는 다음과 같습니다.

1. 귀하의 서비스 또는 컨트롤러에서 사용

<?php

namespace Test\CommonBundle\Services;

use Doctrine\ORM\EntityManagerInterface;

class UserService
{
    private $userRepository;

    // use custom repository over direct use of EntityManager
    // see step 2
    public function __constructor(UserRepository $userRepository)
    {
        $this->userRepository = $userRepository;
    }

    public function getUser($userId)
    {
        return $this->userRepository->find($userId);
    }
}

2. 새 사용자 지정 저장소 만들기

<?php

namespace Test\CommonBundle\Repository;

use Doctrine\ORM\EntityManagerInterface;

class UserRepository
{
    private $repository;

    public function __construct(EntityManagerInterface $entityManager)
    {
        $this->repository = $entityManager->getRepository(UserEntity::class);
    }

    public function find($userId)
    {
        return  $this->repository->find($userId);
    }
}

3. 서비스 등록

# app/config/services.yml
services:
    _defaults:
        autowire: true

    Test\CommonBundle\:
       resource: ../../Test/CommonBundle
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.