在 ZF2 中创建具有依赖关系(依赖注入)的学说存储库

2024-03-10

我想创建一个具有硬依赖关系的存储库。我发现Jurian Sluisman 的这篇博文 https://juriansluiman.nl/article/142/dependency-injection-in-a-doctrine-repository但他建议从服务管理器获取存储库,并在需要时将其注入到服务中。

如果我能够像平常一样从我的应用程序中获取带有注入依赖项的自定义存储库,那就更好了EntityManager or ObjectManager实例通过使用getRepository method:

$objectManager->getRepository('My\Entity\Class');

如何在我的存储库中使用构造函数注入并仍然像平常一样从ObjectManager直接与getRepository method?


教义用途一个工厂类Doctrine\ORM\EntityManagerInterface\DefaultRepositoryFactory https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php用于创建存储库实例。如果未设置自定义工厂,则会创建此默认工厂这里在getRepositoryFactory method https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/Configuration.php#L816 in the Doctrine\ORM\Configuration class https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/Configuration.php.

通过定义自定义repository_factory我们可以覆盖这个默认工厂类并向工厂添加自定义逻辑以注入硬依赖项:

为了说明如何做到这一点,我将展示一个示例,其中存储库工厂类创建依赖于ServiceLocator通过构造函数注入实例。

1)创建一个实现该原则的自定义工厂类RepositoryFactory界面

这个类看上去和学说很相似DefaultRepositoryFactory class.

<?php

namespace My\ORM\Repository;

use Doctrine\Common\Persistence\ObjectRepository;    
use Doctrine\ORM\Repository\RepositoryFactory;
use Doctrine\ORM\EntityManagerInterface;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorAwareTrait;
use Zend\ServiceManager\ServiceLocatorInterface;

class CustomRepositoryFactory implements RepositoryFactory, ServiceLocatorAwareInterface
{
    use ServiceLocatorAwareTrait;

    /**
     * @var ObjectRepository[]
     */
    private $repositoryList = array();

    /**
     * @var ServiceLocator
     */
    protected $serviceLocator;

    /**
     * @param ServiceLocatorInterface $serviceLocator
     */
    public function __construct(ServiceLocatorInterface $serviceLocator)
    {
        $this->serviceLocator = $serviceLocator;
    }

    /**
     * {@inheritdoc}
     */
    public function getRepository(EntityManagerInterface $entityManager, $entityName)
    {
        $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);
    }

    /**
     * @param EntityManagerInterface $entityManager The EntityManager instance.
     * @param string                 $entityName    The name of the entity.
     * @return ObjectRepository
     */
    private function createRepository(EntityManagerInterface $entityManager, $entityName)
    {
        /* @var $metadata \Doctrine\ORM\Mapping\ClassMetadata */
        $metadata            = $entityManager->getClassMetadata($entityName);
        $repositoryClassName = $metadata->customRepositoryClassName
            ?: $entityManager->getConfiguration()->getDefaultRepositoryClassName();

        // Constructor injection, I check with subclass of but it is just an example
        if(is_subclass_of($repositoryClassName, ServiceLocatorAwareInterface::class)){
            $serviceLocator = $this->getServiceLocator()
            $repository = new $repositoryClassName($entityManager, $metadata, $serviceLocator);
        }else{
            $repository = new $repositoryClassName($entityManager, $metadata);
        }
        return $repository;
    }
}

2)为存储库工厂创建一个工厂

<?php
namespace My\ORM\Repository\Factory;

use My\ORM\Repository\CustomRepositoryFactory;
use Zend\Cache\Storage\StorageInterface;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

class CustomRepositoryFactoryFactory implements FactoryInterface
{
    /**
     * @param  ServiceLocatorInterface $serviceLocator
     * @return StorageInterface
     */
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        return new CustomRepositoryFactory($serviceLocator);
    }
}

3)在存储库工厂中注册工厂service_manager config

'service_manager' => array(
    'factories' => array(
        'My\ORM\Repository\CustomRepositoryFactory' => 'My\ORM\Repository\Factory\CustomRepositoryFactoryFactory'
    )
)

4)在学说配置中注册存储库工厂

'doctrine' => array(
    'configuration' => array(
        'orm_default' => array(
            'repository_factory' => 'My\ORM\Repository\CustomRepositoryFactory'
        )
    )
)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 ZF2 中创建具有依赖关系(依赖注入)的学说存储库 的相关文章

随机推荐

  • AT+CUSD 无法在华为 e3131a 调制解调器上工作

    我试图发送 at 命令以在 huawei e3131a 调制解调器上获得平衡 但无论我使用什么配置 GSM IRA UCS2 我总是收到 Ok 作为答案 我还尝试更改操作员代码 123 到许多格式 如十六进制 PDU 简单字符串 但无法获得
  • 使 in 子句将所有项目与任何替代项相匹配?

    我有一张桌子hotel hotelid hotelname etc 和另一张桌子facilities facilityid facilityname 这两个表通过 table 链接hotel to facilities map hoteli
  • 使用从 bash 中的文件读取的数组并行化 while 循环

    我在 Bash 中有一个 while 循环 处理如下 while IFS t read r a line do myprogram line 0 line 1 line 0 vs line 1 result done lt fileinpu
  • 我想禁用特定航空窗口上的阴影效果

    我想禁用特定航空窗口上的阴影效果 我所拥有的只是该窗口的 HWND 这可能吗 阴影由操作系统当前使用的主题定义 您不能仅针对一个窗口禁用它 您可以更改主题并禁用阴影 但这将是系统范围内的更改 而不是特定于某个窗口 就您而言 最好的方法之一是
  • 从 SSIS 执行 SQL 任务返回整数值

    我正在使用 SQL Server 2005 Business Intelligence Studio 并努力从一个非常简单的执行 SQL 任务返回一个整数值 为了一个非常简单的测试 我将 SQL 语句编写为 Select 35 As Tot
  • NSManagedObjectModel - 动态创建模型

    谁能给我指点一下在 Xcode 中动态构建核心数据模型的教程吗 我发现的所有教程都是基于静态设计 但苹果文档说可以以编程方式构建模型 遗憾的是 苹果文档集中没有相关示例 你必须初始化一个NSManagedObjectModel 然后为模型中
  • Bash:无限睡眠(无限阻塞)

    I use startx启动 X 它将评估我的 xinitrc In my xinitrc我使用启动窗口管理器 usr bin mywm 现在 如果我终止我的 WM 为了测试其他 WM X 也会终止 因为 xinitrc脚本到达 EOF 所
  • 如何让 ServiceStack 身份验证发挥作用? (使用 iPhone 客户端)

    我们聘请了一名承包商 他正在为我们编写 iPhone 应用程序 我开始使用 ServiceStack 为其编写后端服务 我在一般授权方面遇到了困难 使用什么样的授权以及如何实现它 我对 ServiceStack HTTP 和授权不太了解 还
  • JFormattedTextField 中严格的 24 小时时间

    我正在尝试创建一个仅接受 24 小时时间的 JFormattedTextField 我非常接近解决方案 但有一种情况以下代码示例不起作用 如果输入时间 222 并从字段中更改焦点 时间将更正为 2202 我希望它只接受完整的 4 位数 24
  • 为 SQL Server 中的特定记录生成脚本

    这可能是一个有限但有价值的场景 我有一个 SQL Server 2008 数据库 其中有一个包含数百万条记录的表 一些记录似乎存在间歇性问题 我正在尝试重现该问题 为了做到这一点 我终于获得了违规记录的 ID 我想在我的 PROD 数据库中
  • 如何从 C# 代码重新启用 Gmail 中的弹出功能?

    我有一个从 Gmail 下载邮件的程序 我选择了单选按钮 为所有邮件启用 POP 甚至是已下载的邮件 下载邮件后 我的 Gmail 将上述状态更改为 对自当前日期以来到达的所有邮件启用 POP 我没有物理更改单选按钮 但它似乎自动将其设置为
  • 如何在剑道网格中加载大量数据

    网页方法
  • calloc(4, 6) 与 calloc(6, 4) 相同吗?

    我是一名初学者 C 程序员 我认为情况会如此 但如果可能的话希望得到一些肯定 如果它们是相同的 为什么不只取一个参数呢 之间没有真正的区别calloc a b and calloc b a 尽管如此 它们都分配相同数量的空间并适当填充它 元
  • 嵌套名称说明符

    我有一个类似的代码 namespace mymap template
  • 可拖动元素的包含

    如何定义可拖动对象的包含区域以使其可拖动到其父元素之外 我有两个可放置的容器 其中有可拖动的 div 我想在容器之间拖动包含的 div 但是 div 落在父容器的边框下方 而不是穿过父容器的边框 如果我设置了非常高的 z 索引 我只能让 d
  • 如何在 HTML5 Canvas 中使用动态旋转值绘制水印?

    我正在使用 HTML5 我正在尝试使用文本在图像上绘制水印 我有以下代码 div style width 612px height 792px div
  • 可可中的自定义主应用程序循环

    我一直在关注 Handmade Hero 项目 其中 Casey Muratori 从头开始 创建了一个完整的游戏引擎 而不使用库 该引擎具有高度可移植性 因为它呈现自己的位图 然后平台特定的代码将其绘制到屏幕上 在 Windows 下 通
  • C++ 类中的内联规则是什么?

    从我很久以前读到的内容来看 如果您希望在编译阶段内联类成员函数 则该函数必须在类声明块内定义 但这有一个缺点 那就是细节泄露 恕我直言 其他程序员在打开 h 文件时应该只看到类接口 第一个陈述在现代 C 中仍然正确吗 有没有办法强制内联声明
  • 错误:“已加载运行时 CuDNN 库:5005 但源是用 5103 编译的”是什么意思?

    我尝试将 TensorFlow 与 GPU 结合使用 但出现以下错误 I tensorflow core common runtime gpu gpu device cc 838 Creating TensorFlow device gpu
  • 在 ZF2 中创建具有依赖关系(依赖注入)的学说存储库

    我想创建一个具有硬依赖关系的存储库 我发现Jurian Sluisman 的这篇博文 https juriansluiman nl article 142 dependency injection in a doctrine reposit