我有一个独立的Symfony软件包(与Composer一起安装),包含实体和存储库,可以在连接相同数据库的应用程序之间共享。
使用配置(显示yml)将实体附加到每个应用程序:
doctrine:
orm:
mappings:
acme:
type: annotation
dir: %kernel.root_dir%/../vendor/acme/entities/src/Entities
prefix: Acme\Entities
alias: Acme
嗯,这是在应用程序中包含外部实体的最简单方法,但看起来有点难看。
每当我从实体经理那里获得存储库时:
$entityManager->getRepository('Acme:User');
我获得预先配置的存储库(在实体配置中)或默认Doctrine\ORM\EntityRepository
。
现在我想覆盖单个实体的捆绑(或默认)存储库类。是否有机会使用某些配置/扩展/等?
我认为,最好看的方式是:
doctrine:
orm:
....:
Acme\Entities\User:
repositoryClass: My\Super\Repository
或者使用标签:
my.super.repository:
class: My\Super\Repository
tags:
- { name: doctrine.custom.repository, entity: Acme\Entities\User }
答案 0 :(得分:5)
您可以使用LoadClassMetadata事件:
class LoadClassMetadataSubscriber implements EventSubscriber
{
/**
* @inheritdoc
*/
public function getSubscribedEvents()
{
return [
Events::loadClassMetadata
];
}
/**
* @param LoadClassMetadataEventArgs $eventArgs
*/
public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
{
/**
* @var \Doctrine\ORM\Mapping\ClassMetadata $classMetadata
*/
$classMetadata = $eventArgs->getClassMetadata();
if ($classMetadata->getName() !== 'Acme\Entities\User') {
return;
}
$classMetadata->customRepositoryClassName = 'My\Super\Repository';
}
}
使用配置(显示yml)将实体附加到每个应用程序: 嗯,这是在应用程序中包含外部实体的最简单方法,但看起来有点难看。
您可以启用auto_mapping
答案 1 :(得分:3)
除了Artur Vesker的回答,我还找到了另一种方式:覆盖全球repository_factory
。
config.yml:
doctrine:
orm:
repository_factory: new.doctrine.repository_factory
services.yml:
new.doctrine.repository_factory:
class: My\Super\RepositoryFactory
存储库工厂:
namespace My\Super;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Repository\DefaultRepositoryFactory;
class RepositoryFactory extends DefaultRepositoryFactory
{
/**
* @inheritdoc
*/
protected function createRepository(EntityManagerInterface $entityManager, $entityName)
{
if ($entityName === Acme\Entities\User::class) {
$metadata = $entityManager->getClassMetadata($entityName);
return new ApplicationRepository($entityManager, $metadata);
}
return parent::createRepository($entityManager, $entityName);
}
}
毫无疑问,实施LoadClassMetadataSubscriber
是一种更好的方法。