如何在Symfony2中注入特定的Doctrine Entity Manager?

Tou*_*uki 13 php symfony doctrine-orm

在使用相同数据库的几个项目上,我们制作了一个Symfony2 Bundle来映射所有常见功能.

现在的问题是我们有第二个数据库,我们需要相同类型的服务,就像第一个一样.

config.yml

doctrine:
  dbal:
    default_connection: main
    connections:
      main:
        /* ... */
      sub:
        /* ... */

  orm:
      default_entity_manager:   main
      entity_managers:
          main:
              connection:       main
              mappings:
                  AcmeMainBundle: ~
          sub:
              connection:       sub
              mappings:
                  AcmeSubBundle: ~
      auto_generate_proxy_classes: %kernel.debug%
Run Code Online (Sandbox Code Playgroud)

@AcmeMainBundle > services.yml

services:
    mainmanager:
      class: Acme\MainBundle\MainManager
      arguments: [ @doctrine.orm.entity_manager ]
Run Code Online (Sandbox Code Playgroud)

Acme\MainBundle\MainManager

class MainManager
{
    public function __construct(EntityManager $em)
    {
        $em->getRepository('AcmeMainBundle:Foo');
    }
}
Run Code Online (Sandbox Code Playgroud)

这个设置工作正常,我得到所有预期的结果,因为default_entity_manager设置为main正确的EntityManager.

但现在这是问题所在.

@AcmeSubBundle > services.yml

submanager:
  class: Acme\SubBundle\SubManager
  arguments: [ @doctrine.orm.entity_manager ]
Run Code Online (Sandbox Code Playgroud)

Acme\SubBundle\SubManager

class SubManager
{
    public function __construct(EntityManager $em)
    {
        $em->getRepository('AcmeSubBundle:Bar'); // Throws exception
    }
}
Run Code Online (Sandbox Code Playgroud)

未知的实体名称空间别名AcmeSubBundle

自从默认EntityManager进入main.

我的问题是,是否有一种"干净"的方式将特定的实体管理器注入services.yml中的参数?

Tou*_*uki 18

回答于18/02/13

以下是从services.yml
Doctrine 传递特定实体管理器的方法,生成相对于其名称的新服务名称.

例:

@doctrine.orm.default_entity_manager
Run Code Online (Sandbox Code Playgroud)

在这种情况下,它会生成另外两个实体管理器

@doctrine.orm.main_entity_manager
@doctrine.orm.sub_entity_manager
Run Code Online (Sandbox Code Playgroud)

传递的参数是一个Doctrine\ORM\EntityManager对象

就我而言:

services.yml

submanager:
    arguments: [ @doctrine.orm.sub_entity_manager ]
Run Code Online (Sandbox Code Playgroud)

2013年8月22日更新

另一种方法是直接提供存储库而不是管理器.

为此,您必须创建一个包含存储库的服务.

services.yml

services:
    acme.foo_repository:
        class: Doctrine\Common\Persistence\ObjectRepository
        factory_service: doctrine.orm.main_entity_manager
        factory_method:  getRepository
        arguments:
            - "AcmeMainBundle:Foo"
Run Code Online (Sandbox Code Playgroud)

我们让doctrine生成给定的存储库.
然后我们可以将它注入另一个服务

services:
    mainmanager:
        class: Acme\MainBundle\MainManager
        arguments:
            - @acme.foo_repository
Run Code Online (Sandbox Code Playgroud)