Symfony3 自定义 Repository Factory

需求:CommonBundle 存放数据库表的映射/实体/持久类, 现有 AdminBundleApiBundle 使用同一数据库, 现在需要将两个BundleRepository分开, 比如有个表为 User, 则需要两个 Repository, 在 CommonBundle 下新建 Admin/UserRepository.phpApi/UserRepository.php, 即将两个BundleRepository放在不同的目录下

创建 EnhancedRepositoryFactory.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<?php

namespace Bundles\CommonBundle\EntityRepository;

use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Repository\RepositoryFactory;

/**
* Factory that set a default EntityRepository for specific entities.
*/
final class EnhancedRepositoryFactory implements RepositoryFactory
{
/**
* The list of EntityRepository instances.
*
* @var \Doctrine\Common\Persistence\ObjectRepository[]
*/
private $repositoryList = [];

/**
* {@inheritdoc}
*/
public function getRepository(EntityManagerInterface $entityManager, $entityName)
{
$port = null;
$explodeArray = explode(':', $entityName);
if (count($explodeArray) > 2) {
list($namespaceAlias, $port, $targetEntity) = $explodeArray;
$entityName = "{$namespaceAlias}:{$targetEntity}";
}

$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, $port);
}

/**
* Create a new repository instance for an entity class.
*
* @param \Doctrine\ORM\EntityManagerInterface $entityManager The EntityManager instance.
* @param string $entityName The name of the entity.
* @param string $port
*
* @return \Doctrine\Common\Persistence\ObjectRepository
*/
private function createRepository(EntityManagerInterface $entityManager, $entityName, $port)
{
/* @var $metadata \Doctrine\ORM\Mapping\ClassMetadata */
$metadata = $entityManager->getClassMetadata($entityName);
if (is_null($port)) {
$repositoryClassName = $metadata->customRepositoryClassName ?: $entityManager->getConfiguration()->getDefaultRepositoryClassName();
} else {
$repositoryClassName = str_replace('\\Entity\\', '\\EntityRepository\\' . $port . '\\', $metadata->name) . 'Repository';
}

return new $repositoryClassName($entityManager, $metadata);
}
}

将 EnhancedRepositoryFactory 注册为服务

1
2
3
4
5
6
7
services:
_defaults:
public: true

#==========================EnhancedRepositoryFactory======================
app.doctrine.repository.factory:
class: Bundles\CommonBundle\EntityRepository\EnhancedRepositoryFactory

配置 config.yml

1
2
3
4
# Doctrine Configuration
doctrine:
orm:
repository_factory: app.doctrine.repository.factory

调用方式

1
2
3
$em = $this->getEntityManager();
$adminUserRepository = $em->getRepository('CommonBundle:Admin:User');
$apiUserRepository = $em->getRepository('CommonBundle:Api:User');
0%