Symfony 3.3将仓库注入到服务中

5
我有一个捆绑包,它在私人Satis仓库中保存,因为其实体和存储库在多个应用程序之间共享。
消费该捆绑包的其他应用程序是Symfony 2.7和2.8应用程序。我正在开发一个新应用程序,并要求使用Symfony 3.3。
在Symfony 3.3应用程序中,我已经在我的services.yml中尝试了这个方法:
# Learn more about services, parameters and containers at
# http://symfony.com/doc/current/service_container.html
parameters:
    #parameter_name: value

services:
# default configuration for services in *this* file
    _defaults:
        autowire: true
        autoconfigure: true
        # this means you cannot fetch services directly from the container via $container->get()
        # if you need to do this, you can override this setting on individual services
        public: false

    # makes classes in src/AppBundle available to be used as services
    # this creates a service per class whose id is the fully-qualified class name
    CbmLtd\UvmsBundle\:
        resource: '../../vendor/cbmltd/uvms-bundle/*'
        exclude: '../../vendor/cbmltd/uvms-bundle/{Entity,Repository}'

    UvmsApiV1Bundle\:
        resource: '../../src/UvmsApiV1Bundle/*'
        exclude: '../../src/UvmsApiV1Bundle/{Entity,Repository}'

以上内容引发了以下异常:
无法自动装配服务“UvmsApiV1Bundle\Service\DealerService”:方法“__construct()”的参数“$repository”引用类“CbmLtd\UvmsBundle\Repository\DealerRepository”,但不存在这样的服务。它不能被自动注册,因为它来自不同的根命名空间。
好的,我猜我需要显式地将此存储库声明为服务。在Symfony 3.3文档中找不到有关将存储库声明为服务的任何信息,而2.8语法也不起作用。
我将以下内容添加到我的services.yml文件中:
services:
    ...
    CbmLtd\UvmsBundle\DealerRepository:
        class: CbmLtd\UvmsBundle\Entity\DealerRepository
        factory_service: doctrine.orm.entity_manager
        factory_method: getRepository
        arguments:
            - CbmLtd\UvmsBundle\Entity\Dealer

但是我仍然会收到这个异常:
无法自动装配服务“UvmsApiV1Bundle\Service\DealerService”:方法“__construct()”的参数“$repository”引用类“CbmLtd\UvmsBundle\Repository\DealerRepository”,但不存在这样的服务。它不能被自动注册,因为它来自不同的根命名空间。
我不能对CbmLtd\UvmsBundle进行任何更改,因为它被多个应用程序使用。如果有帮助,将不胜感激。我已经花费了数小时在这上面,这非常令人沮丧。
4个回答

5

我可以通过以下services.yml文件来实现:

services:
# default configuration for services in *this* file
    _defaults:
        autowire: true
        autoconfigure: true

    # this means you cannot fetch services directly from the container via $container->get()
    # if you need to do this, you can override this setting on individual services
    public: false

    # makes classes in src/AppBundle available to be used as services
    # this creates a service per class whose id is the fully-qualified class name
    CbmLtd\UvmsBundle\:
        resource: '../../vendor/cbmltd/uvms-bundle/*'
        exclude: '../../vendor/cbmltd/uvms-bundle/{Entity,Repository}'

    CbmLtd\UvmsBundle\Repository\DealerRepository:
        factory: doctrine.orm.entity_manager:getRepository
        arguments:
            - CbmLtd\UvmsBundle\Entity\Dealer

    UvmsApiV1Bundle\:
        resource: '../../src/UvmsApiV1Bundle/*'
        exclude: '../../src/UvmsApiV1Bundle/{Entity,Repository}'

我必须稍微改变我的控制器,但现在它能正常工作了。


1

2018年及之后版本和Symfony 3.3及之后版本的答案

您可以进一步使用Repositories as Services

这样,您将利用Symfony的自动装配和服务配置中的易于配置性。

1. 服务

services:
    _defaults:
        autowire: true
        autoconfigure: true

    CbmLtd\UvmsBundle\:
        resource: '../../vendor/cbmltd/uvms-bundle/*'
        exclude: '../../vendor/cbmltd/uvms-bundle/{Entity}'

    UvmsApiV1Bundle\:
        resource: '../../src/UvmsApiV1Bundle/*'
        exclude: '../../src/UvmsApiV1Bundle/{Entity}'

2. 仓库

namespace CbmLtd\UvmsBundle\Repository\DealerRepository;

final class DealerRepository
{
    /**
     * @var Doctrine\ORM\EntityRepository
     */
    private $repository;

    public function __construct(EntityManagerInterface $entityManager)
    {
        $this->repository = $entityManager->getRepository(Dealer::class);
    }

    public function find($id)
    {
        return $this->repository->find($id);
    }
}

-1
尝试更改您的存储库服务声明。
your_bundle.your_entity_repository:
    class: Doctrine\ORM\EntityRepository
    factory: ['@doctrine.orm.default_entity_manager', getRepository]
    arguments:
        - YourBundle\Entity\YourEntity

然后通过像这样引用它来注入 repo:

your_bundle.your_service:
    class: YourBundle\Service\YourService
    arguments:
        - "@your_bundle.your_entity_repository"
    calls:
        - [setContainer, ['@service_container']]

请将类添加到服务"car_base.app.partnership_repository"中,即使它是由工厂构造的,因为我们可能需要根据编译时检查添加方法调用。 (3.4) - itnelo

-1

你的服务声明中有一个拼写错误,你忘记了“repository”命名空间。此外,这个类是在“Entity”还是在“Repository”中?服务ID应该与实际的完全限定类名相同。在services.yml中尝试:

CbmLtd\UvmsBundle\Repository\DealerRepository:
    class: CbmLtd\UvmsBundle\Repository\DealerRepository

与其:

CbmLtd\UvmsBundle\DealerRepository:
    class: CbmLtd\UvmsBundle\Entity\DealerRepository

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接