Hizmette Symfony 2 EntityManager enjeksiyonu


96

Kendi hizmetimi oluşturdum ve EntityManager doktrinini enjekte etmem gerekiyor, ancak bunun __construct()benim hizmetimde çağrıldığını görmüyorum ve enjeksiyon çalışmıyor.

İşte kod ve yapılandırmalar:

<?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  
    }

}

İşte services.ymlpaketimde

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

Bu .yml dosyasını bu şekilde config.ymluygulamama aktardım

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

Ve denetleyicide servisi aradığımda

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

Bir nesne alıyorum (boş değil), ancak $this->emUserService'de boş ve daha önce de bahsettiğim gibi, UserService üzerindeki yapıcı hiç çağrılmadı

Bir şey daha, Controller ve UserService farklı paketlerde (projeyi düzenli tutmak için buna gerçekten ihtiyacım var), ancak yine de: her şey yolunda gidiyor, hatta arayabilirim

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

UserService almak ve geçerli (boş değil) EntityManager nesnesi almak için kullandığım aynı denetleyicide.

Görünüşe göre konfigürasyonun bir parçasını veya UserService ile Doctrine yapılandırması arasında bir bağlantı eksik.


Setter enjeksiyonunu denediniz mi? İşe yarıyor?
gremo

'Ayarlayıcı enjeksiyonu' ile servisimdeki EntityManager için ayarlayıcı yöntemini eklemek ve parametre olarak $ this-> get ('doctrine.orm.entity_manager') ile denetleyiciyi çağırmak istiyorsanız, evet, denedim ve çalışıyor. Ama yapılandırma aracılığıyla doğru enjeksiyonu kullanmayı gerçekten seviyorum
Andrey Zavarin

2
Bunu kastediyorum: symfony.com/doc/current/book/… her neyse __constructor, hatadır.
gremo

Ayarlayıcı enjeksiyonunu denemediğimden daha. __construct sorunu çözdü, ancak yine de yardımınız için teşekkürler!
Andrey Zavarin

Yanıtlar:


112

Sınıfınızın yapıcı yöntemi şu şekilde __construct()değil çağrılmalıdır __constructor():

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

2
Merhaba, bu örnekte, bağlantıyı varsayılandan diğerine nasıl değiştirebilirim?
ptmr.io

Doğru, ama bir arayüz kullanırsanız daha da iyi olur. public function __construct(EntityManagerInterface $entityManager)
Hugues D

65

Modern referans için, Symfony 2.4+ sürümünde artık Constructor Injection yöntemi için argümanları isimlendiremezsiniz. Belgelere göre :

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

Ve sonra argümanlar aracılığıyla listelendikleri sırayla kullanılabilirler (1'den fazla varsa).

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

8
Bir: uygulama / konsol kapsayıcı: hata ayıklama yapabilir ve hangi hizmetleri çalıştırdığınızı da öğrenebilirsiniz.
Hard Fitness

18

Symfony 3.3 ile ilgili not EntityManager amortismana tabi tutulmuştur. Bunun yerine EntityManagerInterface'i kullanın.

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
Herhangi birinin buna rastlaması ve kafası karışması durumunda: EntityManager kesinlikle amortismana tabi tutulmadı. Arayüzün kullanılması otomatik kablolamaya yardımcı olur ve tavsiye edilir, ancak hiçbir şekilde gerekli değildir. Ve arayüz uzun zamandır etrafta. Burada gerçekten yeni bir şey yok.
2018,

Cevap bu. Ancak, lütfen referans yapın: stackoverflow.com/questions/22154558/…
tfont

Kendi çözümüme güncelleyin. Şimdi doğru yol Varlıkları ve Depoları kullanmak olmalıdır. Varlık Yöneticisi zaten bir arşive doğal olarak enjekte edilmiştir. Burada bir örnek görebilirsiniz: youtu.be/AHVtOJDTx0M
Robert Saylor

7

2017 ve Symfony 3,3 beri yapabilirsiniz hizmeti olarak depoyu kayıt sahip olduğu tüm avantajları ile.

Daha genel bir açıklama için Symfony'de Doctrine as Service ile Depo nasıl kullanılır gönderimi kontrol edin .


Özel durumunuza göre, ayarlı orijinal kod şöyle görünecektir:

1. Hizmetlerinizde veya Denetleyicinizde kullanın

<?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. Yeni özel depo oluşturun

<?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. Hizmetleri kaydedin

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

    Test\CommonBundle\:
       resource: ../../Test/CommonBundle
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.