如何在Symfony2中注入一个存储库?

时间:2022-10-16 15:22:48

I need to inject two objects into ImageService. One of them is an instance of Repository/ImageRepository, which I get like this:

我需要向ImageService注入两个对象。其中一个是存储库/ImageRepository实例,我这样做:

$image_repository = $container->get('doctrine.odm.mongodb')
    ->getRepository('MycompanyMainBundle:Image');

So how do I declare that in my services.yml? Here is the service:

那么我该如何在我的服务中声明呢。这是服务:

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);
    }
}

4 个解决方案

#1


98  

Here is a cleaned up solution for those coming from Google like me:

对于像我这样来自谷歌的人,这里有一个干净的解决方案:

Update: here is the Symfony 2.6 (and up) solution:

更新:这里是Symfony 2.6(和up)解决方案:

services:

    myrepository:
        class: Doctrine\ORM\EntityRepository
        factory: ["@doctrine.orm.entity_manager", getRepository]
        arguments:
            - MyBundle\Entity\MyClass

    myservice:
        class: MyBundle\Service\MyService
        arguments:
            - "@myrepository"

Deprecated solution (Symfony 2.5 and less):

不赞成的解决方案(Symfony 2.5及以下):

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"

#2


44  

I found this link and this worked for me:

我找到了这个链接,它对我起了作用:

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%

#3


37  

In case if do not want to define each repository as a service, starting from version 2.4 you can do following, (default is a name of the entity manager):

如果不希望将每个存储库定义为服务,可以从2.4版本开始执行以下操作(默认是实体管理器的名称):

@=service('doctrine.orm.default_entity_manager').getRepository('MycompanyMainBundle:Image')

#4


2  

2017 and Symfony 3.3+ made this much simpler.

2017年和Symfony 3.3+让这一切变得简单多了。

Check my post How to use Repository with Doctrine as Service in Symfony for more general description.

请查看我的文章,了解如何在Symfony中使用存储库作为服务。

To your code, all you need to do is use composition over inheritance - one of SOLID patterns.

对于您的代码,您所需要做的就是使用组合而不是继承—一种可靠的模式。

1. Create own repository without direct dependency on 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. Add config registration with PSR-4 based autoregistration

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

    MycompanyMainBundle\:
        resource: ../../src/MycompanyMainBundle

3. Now you can add any dependency anywhere via constructo injection

use MycompanyMainBundle\Repository\ImageRepository;

class ImageService
{
    public function __construct(ImageRepository $imageRepository)
    {
        $this->imageRepository = $imageRepository;
    }
}

#1


98  

Here is a cleaned up solution for those coming from Google like me:

对于像我这样来自谷歌的人,这里有一个干净的解决方案:

Update: here is the Symfony 2.6 (and up) solution:

更新:这里是Symfony 2.6(和up)解决方案:

services:

    myrepository:
        class: Doctrine\ORM\EntityRepository
        factory: ["@doctrine.orm.entity_manager", getRepository]
        arguments:
            - MyBundle\Entity\MyClass

    myservice:
        class: MyBundle\Service\MyService
        arguments:
            - "@myrepository"

Deprecated solution (Symfony 2.5 and less):

不赞成的解决方案(Symfony 2.5及以下):

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"

#2


44  

I found this link and this worked for me:

我找到了这个链接,它对我起了作用:

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%

#3


37  

In case if do not want to define each repository as a service, starting from version 2.4 you can do following, (default is a name of the entity manager):

如果不希望将每个存储库定义为服务,可以从2.4版本开始执行以下操作(默认是实体管理器的名称):

@=service('doctrine.orm.default_entity_manager').getRepository('MycompanyMainBundle:Image')

#4


2  

2017 and Symfony 3.3+ made this much simpler.

2017年和Symfony 3.3+让这一切变得简单多了。

Check my post How to use Repository with Doctrine as Service in Symfony for more general description.

请查看我的文章,了解如何在Symfony中使用存储库作为服务。

To your code, all you need to do is use composition over inheritance - one of SOLID patterns.

对于您的代码,您所需要做的就是使用组合而不是继承—一种可靠的模式。

1. Create own repository without direct dependency on 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. Add config registration with PSR-4 based autoregistration

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

    MycompanyMainBundle\:
        resource: ../../src/MycompanyMainBundle

3. Now you can add any dependency anywhere via constructo injection

use MycompanyMainBundle\Repository\ImageRepository;

class ImageService
{
    public function __construct(ImageRepository $imageRepository)
    {
        $this->imageRepository = $imageRepository;
    }
}