Symfony 2 EntityManager iniezione in servizio

Ho creato il mio servizio e non ho bisogno di iniettare dottrina EntityManager, ma non vedo che __construct() è chiamato sul mio servizio, e l’iniezione non funziona.

Qui c’è il codice e le configurazioni:

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

}

Qui è services.yml nel mio bundle

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

Ho importato .yml in config.yml nella mia app come quella

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

E quando mi chiama service controller

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

Ho un oggetto (non nullo), ma $this->em in UserService è nullo, e come ho già detto, costruttore su UserService non è mai stato chiamato

Una cosa di più, Controller e UserService sono in diversi bundle, (io ne ho davvero bisogno per mantenere il progetto organizzato), ma ancora: tutto il resto funziona bene, posso anche chiamare

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

nello stesso controller che uso per ottenere UserService e ottenere validi (non null) EntityManager oggetto.

Aspetto che mi manca un pezzo di configurazione o qualche collegamento tra UserService e Dottrina config.

  • Hai cercato un setter? Funziona?
  • Se da ‘un setter’ si intende aggiungere nel metodo setter per EntityManager sul mio servizio e chiamando controller con $this->get(‘dottrina.orm.entity_manager’) come parametro, quindi sì, ho provato e funziona. Ma mi piace molto per un uso corretto di iniezione tramite config
  • Voglio dire questo: symfony.com/doc/current/book/… comunque __constructor è l’errore.
  • Um, che non ho provato un setter. __costruire risolto il problema, ma comunque, grazie per il vostro aiuto!



4 Replies
  1. 112

    Il metodo costruttore della classe dovrebbe essere chiamato __construct(), non __constructor():

    public function __construct(EntityManager $entityManager)
    {
        $this->em = $entityManager;
    }
    • Ciao, in questo esempio, come potrei modificare la connessione di default dall’altro?
  2. 64

    Moderna riferimento, in Symfony 2.4+, non è possibile nominare gli argomenti per il Costruttore metodo di Iniezione di più. Secondo il documentazione passare in:

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

    E quindi sarebbero disponibili nell’ordine in cui sono stati elencati mediante argomenti (se ci sono più di 1).

    public function __construct(EntityManager $entityManager) {
        $this->em = $entityManager;
    }
    • Si può fare: app/console contenitore:debug E scoprire quali servizi sono in esecuzione pure.
  3. 16

    Nota come Symfony 3.3 EntityManager è deprezzato. Utilizzare EntityManagerInterface invece.

    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;
            ...
        }
    }
    • Nel caso qualcuno si imbatte in questo ed è confuso: l’EntityManager non è certo stato ammortizzato. Utilizzando l’interfaccia permette di con auto-cablaggio ed è consigliato ma non obbligatorio. E l’interfaccia è stata intorno per un lungo periodo di tempo. Nulla di veramente nuovo qui.
    • Questa è la risposta. Tuttavia, si prega di fare riferimento: stackoverflow.com/questions/22154558/…
    • Aggiornamento della mia soluzione. Il modo corretto ora dovrebbe essere quello di utilizzare le Entità e Archivi. Ente Gestore è già naturalmente iniettato in un repository. Potete vedere un esempio qui: youtu.essere/AHVtOJDTx0M
  4. 7

    Dal 2017 e Symfony 3.3 è possibile registro Repository come servizio, con tutti i pregi che ha.

    Controllare la mia posta Come utilizzare il Repository con la Dottrina, Servizio in Symfony per ulteriori descrizione generale.


    Al caso specifico, codice originale con la messa a punto sarebbe simile a questa:

    1. Utilizzare nei vostri servizi o Controller

    <?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. Creare un nuovo repository personalizzato

    <?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. Registro servizi

    # app/config/services.yml
    services:
        _defaults:
            autowire: true
    
        Test\CommonBundle\:
           resource: ../../Test/CommonBundle

Lascia un commento