서비스의 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.