问题描述
是否有一种简单的方法可以将依赖项注入 Doctrine2 中的每个存储库实例?
Is there a simple way to inject a dependency into every repository instance in Doctrine2 ?
我试过监听 loadClassMetadata
事件并在存储库上使用 setter 注入,但这自然导致无限循环,因为在事件中调用 getRepository
触发了相同的事件.
I have tried listening to the loadClassMetadata
event and using setter injection on the repository but this naturally resulted in a infinite loop as calling getRepository
in the event triggered the same event.
查看 DoctrineORMEntityManager::getRepository
方法后,似乎存储库根本没有使用依赖注入,而是在函数级别实例化:
After taking a look at the DoctrineORMEntityManager::getRepository
method it seems like repositories are not using dependency injection at all, instead they are instantiated at the function level:
public function getRepository($entityName)
{
$entityName = ltrim($entityName, '\');
if (isset($this->repositories[$entityName])) {
return $this->repositories[$entityName];
}
$metadata = $this->getClassMetadata($entityName);
$customRepositoryClassName = $metadata->customRepositoryClassName;
if ($customRepositoryClassName !== null) {
$repository = new $customRepositoryClassName($this, $metadata);
} else {
$repository = new EntityRepository($this, $metadata);
}
$this->repositories[$entityName] = $repository;
return $repository;
}
有什么想法吗?
推荐答案
如果您使用自定义 EntityManager,您可以覆盖 getRepository
方法.由于这不涉及 loadClassMetadata
事件,因此您不会陷入无限循环.
If you use a custom EntityManager you could override the getRepository
method. Since this doesn't involve the loadClassMetadata
event, you won't run into an infinite loop.
您首先必须将依赖项传递给您的自定义 EntityManager,然后使用 setter 注入将其传递给存储库对象.
You would first have to pass the dependency to your custom EntityManager, and then you'd pass it to the repository object using setter injection.
我回答了如何使用自定义 EntityManager 此处,但我将在下面复制答案:
I answered how to use a custom EntityManager here, but I'll replicate the answer below:
1 - 覆盖 doctrine.orm.entity_manager.class
参数以指向您的自定义实体管理器(它应该扩展 DoctrineORMEntityManager
.)
1 - Override the doctrine.orm.entity_manager.class
parameter to point to your custom entity manager (which should extend DoctrineORMEntityManager
.)
2 - 您的自定义实体管理器必须覆盖 create
方法,以便它返回您的类的实例.请参阅下面的示例,并注意关于 MyEntityManager
的最后一行:
2 - Your custom entity manager must override the create
method so that it returns an instance of your class. See my example below, and note the last line regarding MyEntityManager
:
public static function create($conn, Configuration $config, EventManager $eventManager = null) {
if (!$config->getMetadataDriverImpl()) {
throw ORMException::missingMappingDriverImpl();
}
if (is_array($conn)) {
$conn = DoctrineDBALDriverManager::getConnection($conn, $config, ($eventManager ? : new EventManager()));
} else if ($conn instanceof Connection) {
if ($eventManager !== null && $conn->getEventManager() !== $eventManager) {
throw ORMException::mismatchedEventManager();
}
} else {
throw new InvalidArgumentException("Invalid argument: " . $conn);
}
// This is where you return an instance of your custom class!
return new MyEntityManager($conn, $config, $conn->getEventManager());
}
您还需要在课堂中使用
以下内容:
You'll also need to use
the following in your class:
use DoctrineORMEntityManager;
use DoctrineORMConfiguration;
use DoctrineORMORMException;
use DoctrineCommonEventManager;
use DoctrineDBALConnection;
编辑
由于默认实体管理器是通过 create
方法创建的,您不能简单地将服务注入其中.但是由于您正在制作自定义实体管理器,您可以将其连接到服务容器并注入您需要的任何依赖项.
Since the default entity manager is created from the create
method, you can't simply inject a service into it. But since you're making a custom entity manager, you can wire it up to the service container and inject whatever dependencies you need.
然后在重写的 getRepository
方法中,您可以执行类似$repository->setFoo($this->foo)
.这是一个非常简单的例子——你可能想在调用它之前先检查 $repository
是否有一个 setFoo
方法.实现由您决定,但这展示了如何对存储库使用 setter 注入.
Then from within the overridden getRepository
method you could do something like$repository->setFoo($this->foo)
. That's a very simple example - you may want to first check if $repository
has a setFoo
method before calling it. The implementation is up to you, but this shows how to use setter injection for a repository.
这篇关于将依赖注入实体存储库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!