php - ejemplo - Crear un repositorio de doctrina con dependencias(inyección de dependencia) en ZF2
inyeccion de dependencias php (1)
Quiero hacer un repositorio con dependencias duras. Encontré esta publicación en el blog de Jurian Sluisman, pero él sugiere obtener el repositorio del administrador del servicio e inyectarlo en el servicio cuando sea necesario.
Sería mucho mejor si pudiera obtener mis repositorios personalizados con dependencias inyectadas como normalmente desde mi instancia EntityManager
o ObjectManager
utilizando el método getRepository
:
$objectManager->getRepository(''My/Entity/Class'');
¿Cómo puedo usar la inyección de constructor en mis Repositorios y todavía obtenerlos como normalmente desde el ObjectManager
directamente con el método getRepository
?
Doctrine utiliza una clase de fábrica Doctrine/ORM/EntityManagerInterface/DefaultRepositoryFactory
para crear instancias de repositorio. Si no se establece fábrica personalizada, esta fábrica predeterminada se crea aquí en el método getRepositoryFactory
en la clase Doctrine/ORM/Configuration
.
Al definir un repository_factory
personalizado, podemos sobreescribir esta clase de fábrica predeterminada y agregar lógica personalizada a la fábrica que inyectará las dependencias duras:
Para ilustrar cómo puede hacer esto, mostraré un ejemplo en el que la clase de fábrica de repositorio crea repositorios que dependen de una instancia de ServiceLocator
través de la inyección del constructor.
1) hacer una clase de fábrica personalizada que implemente la interfaz doctrina RepositoryFactory
Esta clase se ve muy similar a la doctrina clase DefaultRepositoryFactory
.
<?php
namespace My/ORM/Repository;
use Doctrine/Common/Persistence/ObjectRepository;
use Doctrine/ORM/Repository/RepositoryFactory;
use Doctrine/ORM/EntityManagerInterface;
use Zend/ServiceManager/ServiceLocatorAwareInterface;
use Zend/ServiceManager/ServiceLocatorAwareTrait;
use Zend/ServiceManager/ServiceLocatorInterface;
class CustomRepositoryFactory implements RepositoryFactory, ServiceLocatorAwareInterface
{
use ServiceLocatorAwareTrait;
/**
* @var ObjectRepository[]
*/
private $repositoryList = array();
/**
* @var ServiceLocator
*/
protected $serviceLocator;
/**
* @param ServiceLocatorInterface $serviceLocator
*/
public function __construct(ServiceLocatorInterface $serviceLocator)
{
$this->serviceLocator = $serviceLocator;
}
/**
* {@inheritdoc}
*/
public function getRepository(EntityManagerInterface $entityManager, $entityName)
{
$repositoryHash = $entityManager->getClassMetadata($entityName)->getName() . spl_object_hash($entityManager);
if (isset($this->repositoryList[$repositoryHash])) {
return $this->repositoryList[$repositoryHash];
}
return $this->repositoryList[$repositoryHash] = $this->createRepository($entityManager, $entityName);
}
/**
* @param EntityManagerInterface $entityManager The EntityManager instance.
* @param string $entityName The name of the entity.
* @return ObjectRepository
*/
private function createRepository(EntityManagerInterface $entityManager, $entityName)
{
/* @var $metadata /Doctrine/ORM/Mapping/ClassMetadata */
$metadata = $entityManager->getClassMetadata($entityName);
$repositoryClassName = $metadata->customRepositoryClassName
?: $entityManager->getConfiguration()->getDefaultRepositoryClassName();
// Constructor injection, I check with subclass of but it is just an example
if(is_subclass_of($repositoryClassName, ServiceLocatorAwareInterface::class)){
$serviceLocator = $this->getServiceLocator()
$repository = new $repositoryClassName($entityManager, $metadata, $serviceLocator);
}else{
$repository = new $repositoryClassName($entityManager, $metadata);
}
return $repository;
}
}
2) Crear una fábrica para la fábrica de repositorios
<?php
namespace My/ORM/Repository/Factory;
use My/ORM/Repository/CustomRepositoryFactory;
use Zend/Cache/Storage/StorageInterface;
use Zend/ServiceManager/FactoryInterface;
use Zend/ServiceManager/ServiceLocatorInterface;
class CustomRepositoryFactoryFactory implements FactoryInterface
{
/**
* @param ServiceLocatorInterface $serviceLocator
* @return StorageInterface
*/
public function createService(ServiceLocatorInterface $serviceLocator)
{
return new CustomRepositoryFactory($serviceLocator);
}
}
3) registrar la fábrica para la fábrica de repositorios en la configuración service_manager
''service_manager'' => array(
''factories'' => array(
''My/ORM/Repository/CustomRepositoryFactory'' => ''My/ORM/Repository/Factory/CustomRepositoryFactoryFactory''
)
)
4) registrar la fábrica de repositorios en la configuración de doctrina
''doctrine'' => array(
''configuration'' => array(
''orm_default'' => array(
''repository_factory'' => ''My/ORM/Repository/CustomRepositoryFactory''
)
)
)