使用 EntityManagerDecorator 扩展 Doctrine EntityManager 在 UnitOfWork 中留下错误的引用
Extending Doctrine EntityManager with EntityManagerDecorator leaves wrong reference in UnitOfWork
我正在尝试使用 EntityManagerDecorator
扩展 Doctrine 中的 EntityManager
并使 运行 在 [=] 中引用基础 EntityManager
成为问题16=] 通过 $eventArgs
.
传递给 prePersist
事件
看起来 EntityManager
在创建 UnitOfWork
时传递给了 EntityManager::__construct
中的 UnitOfWork
。
我认为一个解决方案可能是我可以覆盖 MyEntityManagerDecorator::getUnitOfWork()
中的默认值 UnitOfWork
,例如:
public function getUnitOfWork()
{
if ($this->unitOfWork === null) {
$this->unitOfWork = new UnitOfWork($this);
}
return $this->unitOfWork;
}
但是我注意到 UnitOfWork::__construct()
需要 EntityManager
而不是 EntityManagerInterface
所以这行不通。
我正在寻找如何从 prePersist $eventArgs->getEntityManager()
而不是基础 EntityManager
获得 MyEntityManagerDecorator
。我想这样做而不直接继承 EntityManager
。文档还说 "You should never attempt to inherit from the EntityManager: Inheritance is not a valid extension point for the EntityManager.".
我不确定您需要什么代码示例(如果有),所以如果您需要更多信息,请告诉我。我可以按预期在项目的其他任何地方访问 MyEntityManagerDecorator
(到目前为止我已经尝试过了)。我在 yml
中设置装饰器,如下所示:
my_multi_tenant_entity_manager:
public: false
class: My\MultiTenantBundle\ORM\MyEntityManagerDecorator
decorates: doctrine.orm.default_entity_manager
arguments: [ "@my_multi_tenant_entity_manager.inner" ]
这是我使用的从 composer 转储的软件包和版本号的列表:
installed:
doctrine/annotations v1.2.3 Docblock Annotations Parser
doctrine/cache v1.4.0 Caching library offering...
doctrine/collections v1.2 Collections Abstraction ...
doctrine/common v2.4.2 Common Library for Doctr...
doctrine/dbal v2.5.1 Database Abstraction Layer
doctrine/doctrine-bundle v1.3.0 Symfony DoctrineBundle
doctrine/doctrine-cache-bundle v1.0.1 Symfony2 Bundle for Doct...
doctrine/doctrine-migrations-bundle dev-master 6a1bd73 Symfony DoctrineMigratio...
doctrine/inflector v1.0.1 Common String Manipulati...
doctrine/instantiator 1.0.4 A small, lightweight uti...
doctrine/lexer v1.0.1 Base library for a lexer...
doctrine/migrations dev-master 058a463 Database Schema migratio...
doctrine/orm v2.4.7 Object-Relational-Mapper...
incenteev/composer-parameter-handler v2.1.0 Composer script handling...
jdorn/sql-formatter v1.2.17 a PHP SQL highlighting l...
kriswallsmith/assetic v1.2.1 Asset Management for PHP
monolog/monolog 1.12.0 Sends your logs to files...
phpdocumentor/reflection-docblock 2.0.4
phpspec/prophecy v1.3.1 Highly opinionated mocki...
phpunit/php-code-coverage 2.0.15 Library that provides co...
phpunit/php-file-iterator 1.3.4 FilterIterator implement...
phpunit/php-text-template 1.2.0 Simple template engine.
phpunit/php-timer 1.0.5 Utility class for timing
phpunit/php-token-stream 1.4.0 Wrapper around PHP's tok...
phpunit/phpunit 4.5.0 The PHP Unit Testing fra...
phpunit/phpunit-mock-objects 2.3.0 Mock Object library for ...
psr/log 1.0.0 Common interface for log...
raven/raven dev-master 407d770 A PHP client for Sentry ...
sebastian/comparator 1.1.1 Provides the functionali...
sebastian/diff 1.2.0 Diff implementation
sebastian/environment 1.2.1 Provides functionality t...
sebastian/exporter 1.2.0 Provides the functionali...
sebastian/global-state 1.0.0 Snapshotting of global s...
sebastian/recursion-context 1.0.0 Provides functionality t...
sebastian/version 1.0.4 Library that helps with ...
sensio/distribution-bundle v3.0.16 Base bundle for Symfony ...
sensio/framework-extra-bundle v3.0.4 This bundle provides a w...
sensio/generator-bundle v2.5.2 This bundle generates co...
sensiolabs/security-checker v2.0.1 A security checker for y...
swiftmailer/swiftmailer v5.3.1 Swiftmailer, free featur...
symfony/assetic-bundle v2.6.1 Integrates Assetic into ...
symfony/monolog-bundle v2.7.1 Symfony MonologBundle
symfony/swiftmailer-bundle v2.3.8 Symfony SwiftmailerBundle
symfony/symfony v2.6.4 The Symfony PHP framework
twig/extensions v1.2.0 Common additional featur...
twig/twig v1.18.0 Twig, the flexible, fast...
我建议修饰(而不是直接扩展)EntityManager
,因为它会松散您的实现与继承组件之间的耦合。
为了能够区分与租户 implement/extend 有关系的实体,那些 类 与 interface
或 mapped superclass
。
securityContext(用于演示目的)用于获取对租户的引用。
/**
* `EntityManagerDecorator` exists since v2.4
*/
class MultiTenantEntityManager extends EntityManagerDecorator {
private $securityContext;
public function __construct(EntityManagerInterface $entityManager, $securityContext) {
parent::__construct($entityManager);
$this->securityContext = $securityContext;
}
public function persist($entity) {
// set the tenant before persisting an entity
if ($entity instanceof MultiTenantEntity) {
$userId = $this->securityContext->getUserId();
$tenant = $this->wrapped->find($userId,...);
$entity->setTenant($tenant);
}
return $this->wrapped->persist($entity);
}
}
我正在尝试使用 EntityManagerDecorator
扩展 Doctrine 中的 EntityManager
并使 运行 在 [=] 中引用基础 EntityManager
成为问题16=] 通过 $eventArgs
.
prePersist
事件
看起来 EntityManager
在创建 UnitOfWork
时传递给了 EntityManager::__construct
中的 UnitOfWork
。
我认为一个解决方案可能是我可以覆盖 MyEntityManagerDecorator::getUnitOfWork()
中的默认值 UnitOfWork
,例如:
public function getUnitOfWork()
{
if ($this->unitOfWork === null) {
$this->unitOfWork = new UnitOfWork($this);
}
return $this->unitOfWork;
}
但是我注意到 UnitOfWork::__construct()
需要 EntityManager
而不是 EntityManagerInterface
所以这行不通。
我正在寻找如何从 prePersist $eventArgs->getEntityManager()
而不是基础 EntityManager
获得 MyEntityManagerDecorator
。我想这样做而不直接继承 EntityManager
。文档还说 "You should never attempt to inherit from the EntityManager: Inheritance is not a valid extension point for the EntityManager.".
我不确定您需要什么代码示例(如果有),所以如果您需要更多信息,请告诉我。我可以按预期在项目的其他任何地方访问 MyEntityManagerDecorator
(到目前为止我已经尝试过了)。我在 yml
中设置装饰器,如下所示:
my_multi_tenant_entity_manager:
public: false
class: My\MultiTenantBundle\ORM\MyEntityManagerDecorator
decorates: doctrine.orm.default_entity_manager
arguments: [ "@my_multi_tenant_entity_manager.inner" ]
这是我使用的从 composer 转储的软件包和版本号的列表:
installed:
doctrine/annotations v1.2.3 Docblock Annotations Parser
doctrine/cache v1.4.0 Caching library offering...
doctrine/collections v1.2 Collections Abstraction ...
doctrine/common v2.4.2 Common Library for Doctr...
doctrine/dbal v2.5.1 Database Abstraction Layer
doctrine/doctrine-bundle v1.3.0 Symfony DoctrineBundle
doctrine/doctrine-cache-bundle v1.0.1 Symfony2 Bundle for Doct...
doctrine/doctrine-migrations-bundle dev-master 6a1bd73 Symfony DoctrineMigratio...
doctrine/inflector v1.0.1 Common String Manipulati...
doctrine/instantiator 1.0.4 A small, lightweight uti...
doctrine/lexer v1.0.1 Base library for a lexer...
doctrine/migrations dev-master 058a463 Database Schema migratio...
doctrine/orm v2.4.7 Object-Relational-Mapper...
incenteev/composer-parameter-handler v2.1.0 Composer script handling...
jdorn/sql-formatter v1.2.17 a PHP SQL highlighting l...
kriswallsmith/assetic v1.2.1 Asset Management for PHP
monolog/monolog 1.12.0 Sends your logs to files...
phpdocumentor/reflection-docblock 2.0.4
phpspec/prophecy v1.3.1 Highly opinionated mocki...
phpunit/php-code-coverage 2.0.15 Library that provides co...
phpunit/php-file-iterator 1.3.4 FilterIterator implement...
phpunit/php-text-template 1.2.0 Simple template engine.
phpunit/php-timer 1.0.5 Utility class for timing
phpunit/php-token-stream 1.4.0 Wrapper around PHP's tok...
phpunit/phpunit 4.5.0 The PHP Unit Testing fra...
phpunit/phpunit-mock-objects 2.3.0 Mock Object library for ...
psr/log 1.0.0 Common interface for log...
raven/raven dev-master 407d770 A PHP client for Sentry ...
sebastian/comparator 1.1.1 Provides the functionali...
sebastian/diff 1.2.0 Diff implementation
sebastian/environment 1.2.1 Provides functionality t...
sebastian/exporter 1.2.0 Provides the functionali...
sebastian/global-state 1.0.0 Snapshotting of global s...
sebastian/recursion-context 1.0.0 Provides functionality t...
sebastian/version 1.0.4 Library that helps with ...
sensio/distribution-bundle v3.0.16 Base bundle for Symfony ...
sensio/framework-extra-bundle v3.0.4 This bundle provides a w...
sensio/generator-bundle v2.5.2 This bundle generates co...
sensiolabs/security-checker v2.0.1 A security checker for y...
swiftmailer/swiftmailer v5.3.1 Swiftmailer, free featur...
symfony/assetic-bundle v2.6.1 Integrates Assetic into ...
symfony/monolog-bundle v2.7.1 Symfony MonologBundle
symfony/swiftmailer-bundle v2.3.8 Symfony SwiftmailerBundle
symfony/symfony v2.6.4 The Symfony PHP framework
twig/extensions v1.2.0 Common additional featur...
twig/twig v1.18.0 Twig, the flexible, fast...
我建议修饰(而不是直接扩展)EntityManager
,因为它会松散您的实现与继承组件之间的耦合。
为了能够区分与租户 implement/extend 有关系的实体,那些 类 与 interface
或 mapped superclass
。
securityContext(用于演示目的)用于获取对租户的引用。
/**
* `EntityManagerDecorator` exists since v2.4
*/
class MultiTenantEntityManager extends EntityManagerDecorator {
private $securityContext;
public function __construct(EntityManagerInterface $entityManager, $securityContext) {
parent::__construct($entityManager);
$this->securityContext = $securityContext;
}
public function persist($entity) {
// set the tenant before persisting an entity
if ($entity instanceof MultiTenantEntity) {
$userId = $this->securityContext->getUserId();
$tenant = $this->wrapped->find($userId,...);
$entity->setTenant($tenant);
}
return $this->wrapped->persist($entity);
}
}