php - services - symfony servicios
¿Cómo inyectar un repositorio en un servicio en Symfony2? (4)
Aquí hay una solución limpia para aquellos que vienen de Google como yo:
Actualización: aquí está la solución Symfony 2.6 (y superior):
services:
myrepository:
class: Doctrine/ORM/EntityRepository
factory: ["@doctrine.orm.entity_manager", getRepository]
arguments:
- MyBundle/Entity/MyClass
myservice:
class: MyBundle/Service/MyService
arguments:
- "@myrepository"
Solución obsoleta (Symfony 2.5 y menos):
services:
myrepository:
class: Doctrine/ORM/EntityRepository
factory_service: doctrine.orm.entity_manager
factory_method: getRepository
arguments:
- MyBundle/Entity/MyClass
myservice:
class: MyBundle/Service/MyService
arguments:
- "@myrepository"
Necesito inyectar dos objetos en ImageService
. Una de ellas es una instancia de Repository/ImageRepository
, que obtengo así:
$image_repository = $container->get(''doctrine.odm.mongodb'')
->getRepository(''MycompanyMainBundle:Image'');
Entonces, ¿cómo declaro eso en my services.yml? Aquí está el servicio:
namespace Mycompany/MainBundle/Service/Image;
use Doctrine/ODM/MongoDB/DocumentRepository;
class ImageManager {
private $manipulator;
private $repository;
public function __construct(ImageManipulatorInterface $manipulator, DocumentRepository $repository) {
$this->manipulator = $manipulator;
$this->repository = $repository;
}
public function findAll() {
return $this->repository->findAll();
}
public function createThumbnail(ImageInterface $image) {
return $this->manipulator->resize($image->source(), 300, 200);
}
}
En caso de que no desee definir cada repositorio como un servicio, a partir de la versión 2.4
puede hacer lo siguiente (por default
es un nombre del administrador de la entidad):
@=service(''doctrine.orm.default_entity_manager'').getRepository(''MycompanyMainBundle:Image'')
Encontré este symfony.com/doc/master/components/dependency_injection/… y esto funcionó para mí:
parameters:
image_repository.class: Mycompany/MainBundle/Repository/ImageRepository
image_repository.factory_argument: ''MycompanyMainBundle:Image''
image_manager.class: Mycompany/MainBundle/Service/Image/ImageManager
image_manipulator.class: Mycompany/MainBundle/Service/Image/ImageManipulator
services:
image_manager:
class: %image_manager.class%
arguments:
- @image_manipulator
- @image_repository
image_repository:
class: %image_repository.class%
factory_service: doctrine.odm.mongodb
factory_method: getRepository
arguments:
- %image_repository.factory_argument%
image_manipulator:
class: %image_manipulator.class%
2017 y Symfony 3.3+ hicieron esto mucho más simple.
Verifique mi publicación Cómo usar el repositorio con Doctrine como servicio en Symfony para una descripción más general.
Para su código, todo lo que necesita hacer es usar composición sobre herencia , uno de los patrones SÓLIDOS.
1. Crea tu propio repositorio sin dependencia directa de Doctrine
<?php
namespace MycompanyMainBundle/Repository;
use Doctrine/ORM/EntityManagerInterface;
use MycompanyMainBundle/Entity/Image;
class ImageRepository
{
private $repository;
public function __construct(EntityManagerInterface $entityManager)
{
$this->repository = $entityManager->getRepository(Image::class);
}
// add desired methods here
public function findAll()
{
return $this->repository->findAll();
}
}
2. Agregue el registro de configuración con el registro automático basado en PSR-4
# app/config/services.yml
services:
_defaults:
autowire: true
MycompanyMainBundle/:
resource: ../../src/MycompanyMainBundle
3. Ahora puede agregar cualquier dependencia en cualquier lugar a través de la inyección constructo
use MycompanyMainBundle/Repository/ImageRepository;
class ImageService
{
public function __construct(ImageRepository $imageRepository)
{
$this->imageRepository = $imageRepository;
}
}