dittto / doctrine-entity-factories
允许 Doctrine 从工厂中拉取实体,而不是仅通过反射
Requires (Dev)
- laravel-doctrine/orm: 1.3.*
- mockery/mockery: ^0.9.9
- phpunit/phpunit: ^5.7
- sensio/framework-extra-bundle: ^3.0
- symfony/dependency-injection: ^3.0
- symfony/http-foundation: ^3.0
This package is not auto-updated.
Last update: 2024-09-29 04:03:31 UTC
README
由于使用简单的 PHP 对象作为实体,Doctrine 是一个非常易于使用的 ORM。它通过反射实例化这些实体。然而,如果您想要使用依赖注入来依赖另一个对象的实体,那么您就只能使用设置器注入。
此代码允许您从工厂中拉取新实体,从而实现构造函数注入和更干净的代码。
如何使用
首先,安装此插件。
composer require dittto/doctrine-entity-factories
接下来,让我们为我们的实体创建一个工厂。这些需要实现 EntityFactoryInterface
。
<?php namespace App\Entities\Factories; use App\Entities\TestEntity; use Dittto\DoctrineEntityFactories\Doctrine\ORM\Mapping\EntityFactoryInterface; use Illuminate\Contracts\Validation\Validator; class TestEntityFactory implements EntityFactoryInterface { private $validator; public function __construct(Validator $validator) { $this->validator = $validator; } public function getEntity() { return new TestEntity($this->validator); } }
使用 Doctrine 最常见的框架是 Symfony,但您也可以使用 Doctrine 与 Laravel。以下是如何在两者中使用它的说明。
使用 Laravel
要使用 Laravel 中的 Doctrine,您可以使用这个有用的插件
composer require laravel-doctrine/orm:1.3.* php artisan vendor:publish --tag="config"
我们将使用一个自定义提供者和该插件中存在的提供者。自定义提供者如下
<?php namespace App\Providers; use App\Entities\Factories\TestEntityFactoryInterface; use App\Entities\TestEntity; use Dittto\DoctrineEntityFactories\Doctrine\ORM\Mapping\EntityFactoryAware; use Dittto\DoctrineEntityFactories\Doctrine\ORM\Provider\AbstractEntityFactoryServiceProvider; class EntityFactoryServiceProvider extends AbstractEntityFactoryServiceProvider { public function registerEntityFactories(EntityFactoryAware $entityFactoryRegister) { $entityFactoryRegister->addEntityFactory( TestEntity::class, new TestEntityFactory($this->app->make('hash')) ); } }
此提供者延迟所有对象。您还可以通过扩展 register()
和 provides()
将 new TestEntityFactory
转换为另一个对象。
接下来,我们将提供者添加到主应用配置中
<?php // config/app.php return [ 'providers' => [ App\Providers\DoctrineServiceProvider::class, \Dittto\DoctrineEntityFactories\Doctrine\ORM\Provider\DoctrineServiceProvider::class, ], ];
最后,我们需要修改 doctrine 配置以使用我们的插件
<?php return [ 'managers' => [ 'default' => [ 'meta' => env('DOCTRINE_METADATA', 'yaml_with_entity_factories'), ] ] ];
使用 Symfony
与 Symfony 的许多事物一样,我们可以使用配置来完成几乎所有的事情。
首先,我们需要告诉 Symfony 使用我们的元数据工厂而不是默认的 Doctrine 一个
# app/config/config.yml doctrine: orm: entity_managers: default: class_metadata_factory_name: Dittto\DoctrineEntityFactories\Doctrine\ORM\Mapping\ClassMetadataFactoryWithEntityFactories
如果您使用多个实体管理器,这可能会略有不同,但您可能也理解如何让您的代码工作。
Laravel 允许我们通过其服务提供者轻松加载附加代码。对于 Symfony,我们将采取稍微不同的方法,并装饰 Doctrine 的 EntityManager。这两种方法的目标都是相同的 - 在 Doctrine 开始创建实体之前将其实体工厂添加到其中。
对于 Symfony,我们将添加一些新服务
services: dittto.doctrine_entity_factories.entity_factory_manager_decorator: public: false class: Dittto\DoctrineEntityFactories\Doctrine\ORM\Decorator\EntityFactoryManagerDecorator decorates: doctrine.orm.default_entity_manager arguments: [ "@dittto.doctrine_entity_factories.entity_factory_manager_decorator.inner" ] calls: - [addEntityFactory, ['App\Entities\TestEntity', '@app.entities.factory.test']] app.entities.factory.test: class: App\Entities\Factories\Testfactory arguments: ['@validator']
这里我们将使用 calls
定义来添加我们所需的实体工厂。第一个字段是要由工厂创建的实体的完整类名。
这里的命名空间看起来非标准,但这纯粹是为了与上面的示例绑定。
测试
此插件自带测试。要运行这些测试,克隆代码并导航到目录。然后运行以下命令
composer install ./vendor/bin/phpunit