【发布时间】:2014-08-11 10:15:51
【问题描述】:
我在 Symfony 2 项目中的 Doctrine 2 中设置了一个自定义水合器,但要让它完成它需要的工作,它需要另一个服务。 documentation for custom hydrators 只展示了如何提供 hydrator 类,因此无法注入依赖项。
例如:
$em->getConfiguration()->addCustomHydrationMode('CustomHydrator', 'MyProject\Hydrators\CustomHydrator');
我怀疑 Doctrine 正在初始化 hydrator 本身,因此任何依赖项都需要首先通过其他一些 Doctrine 类。
有没有办法提供自定义的“水合工厂”或类似于 Doctrine 的允许注入额外依赖项的方法?如果没有此功能,自定义水合器似乎相当有限。
答案:感谢 Denis V
我得到这个工作如下。我无法发布实际代码,所以我将一些虚拟占位符放在一起,以便您查看它是如何组合在一起的。
src/Acme/ExampleBundle/resources/config/services.yml
services:
doctrine.orm.entity_manager.abstract:
class: Acme\ExampleBundle\Entity\DoctrineEntityManager
factory_class: Acme\ExampleBundle\Entity\DoctrineEntityManager
factory_method: create
abstract: true
calls:
- [ setMyDependency, [@acme.my_custom_service]]
src/Acme/ExampleBundle/Entity/DoctrineEntityManager.php
namespace Acme\ExampleBundle\Entity;
use Acme\ExampleBundle\Hydrator\MyHydrator;
use Doctrine\Common\EventManager;
use Doctrine\DBAL\Connection;
use Doctrine\ORM\Configuration;
use Doctrine\ORM\EntityManager as BaseEntityManager;
use Doctrine\ORM\ORMException;
use Doctrine\ORM\Query;
class DoctrineEntityManager extends BaseEntityManager
{
protected $myDependency;
/**
* Note: This must be redefined as Doctrine's own entity manager has its own class name hardcoded in.
*/
public static function create($conn, Configuration $config, EventManager $eventManager = null)
{
if (!$config->getMetadataDriverImpl()) {
throw ORMException::missingMappingDriverImpl();
}
switch (true) {
case (is_array($conn)):
$conn = \Doctrine\DBAL\DriverManager::getConnection(
$conn, $config, ($eventManager ?: new EventManager())
);
break;
case ($conn instanceof Connection):
if ($eventManager !== null && $conn->getEventManager() !== $eventManager) {
throw ORMException::mismatchedEventManager();
}
break;
default:
throw new \InvalidArgumentException("Invalid argument: " . $conn);
}
return new self($conn, $config, $conn->getEventManager());
}
public function setMyDependency($myCustomService)
{
$this->myDependency = $myCustomService;
}
public function newHydrator($hydrationMode)
{
if ($hydrationMode == 'MyHydrationMode') {
return new MyHydrator($this, $this->myDependency);
}
return parent::newHydrator($hydrationMode);
}
}
src/Acme/ExampleBundle/Hydrator/MyHydrator.php
namespace Acme\ExampleBundle\Hydrator;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Internal\Hydration\ObjectHydrator;
class MyHydrator extends ObjectHydrator
{
protected $myDependency;
public __construct(EntityManager $em, $myDependency)
{
parent::__construct($em);
$this->myDependency = $myDependency;
}
protected function hydrateAllData()
{
/* hydration stuff with my dependency here */
}
}
【问题讨论】:
标签: php symfony orm doctrine-orm doctrine