将依赖注入实体存储库 [英] Injecting dependency into entity repository

查看:31
本文介绍了将依赖注入实体存储库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有一种简单的方法可以将依赖项注入 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.

这篇关于将依赖注入实体存储库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆