J'ai créé mon propre service et je dois injecter doctrine EntityManager, mais je ne vois pas que __construct()
] est appelé sur mon service et l'injection ne fonctionne pas. .
Voici le code et les configs:
<?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
}
}
Voici services.yml
dans mon paquet
services:
test.common.userservice:
class: Test\CommonBundle\Services\UserService
arguments:
entityManager: "@doctrine.orm.entity_manager"
J'ai importé ce .yml dans config.yml
dans mon application comme ça
imports:
# a few lines skipped, not relevant here, i think
- { resource: "@TestCommonBundle/Resources/config/services.yml" }
Et quand j'appelle le service dans le contrôleur
$userservice = $this->get('test.common.userservice');
$userservice->getUser(123);
Je reçois un objet (non nul), mais $this->em
dans UserService est null et, comme je l’ai déjà mentionné, le constructeur de UserService n’a jamais été appelé.
Une dernière chose, Controller et UserService sont dans des bundles différents (j'ai vraiment besoin de ça pour garder le projet organisé), mais quand même: tout le reste fonctionne bien, je peux même appeler
$this->get('doctrine.orm.entity_manager')
dans le même contrôleur que j'utilise pour obtenir UserService et obtenir un objet EntityManager valide (non nul).
Apparemment, il me manque un élément de configuration ou un lien entre UserService et Doctrine config.
La méthode de constructeur de votre classe doit s'appeler __construct()
, pas __constructor()
:
public function __construct(EntityManager $entityManager)
{
$this->em = $entityManager;
}
Pour référence moderne, dans Symfony 2.4+, vous ne pouvez plus nommer les arguments de la méthode Constructor Injection. Selon le documentation Vous transmettriez:
services:
test.common.userservice:
class: Test\CommonBundle\Services\UserService
arguments: [ "@doctrine.orm.entity_manager" ]
Et ensuite, ils seraient disponibles dans l'ordre dans lequel ils ont été listés via les arguments (s'il y en a plus que 1).
public function __construct(EntityManager $entityManager) {
$this->em = $entityManager;
}
Remarque à partir de Symfony 3.3, EntityManager est amorti. Utilisez EntityManagerInterface à la place.
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;
...
}
}
Depuis 2017 et Symfony 3.3 , vous pouvez enregistrer le référentiel en tant que service , avec ses avantages il a.
Vérifiez mon message Comment utiliser le référentiel avec Doctrine en tant que service dans Symfony pour des informations plus générales la description.
Pour votre cas spécifique, le code d'origine avec réglage ressemblerait à ceci:
<?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);
}
}
<?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);
}
}
# app/config/services.yml
services:
_defaults:
autowire: true
Test\CommonBundle\:
resource: ../../Test/CommonBundle