如何正确地将ObjectManager注入Fieldsets?

时间:2014-04-27 08:51:44

标签: dependency-injection doctrine-orm zend-framework2 entitymanager fieldset

我正在努力将Doctrine的ObjectManager正确注入我的Fieldsets。我不想将它传递给所有构造函数。案例如下:

控制器:

  • 控制器没有ObjectManager。
  • 控制器使用服务。

服务:

  • 服务实现ObjectManagerAwareInterface。
  • Services通过Initializer类获取ObjectManager。
  • 服务提供表格。

形式:

  • 表单不应该有ObjectManager - 至少到目前为止它们不需要。
  • 表单创建相应的字段集。

字段集:

  • Fieldsets实现ObjectManagerAwareInterface。

现在我将ObjectManager 服务通过表单传递给 Fieldset。这种做法非常难看。

我知道有一个使用FormElementManager的解决方案。但是为了做到这一点,我必须通过注入它来向FormLocator提供Form访问权限。这种方法似乎不比我现在的方法更合适。

问题是如何将Doctrine的ObjectManager注入到我的Fieldsets中,而不将全局ServiceLocator(或其他东西)注入到我的Forms中。如果可能的话,我想保留简单的表格。

以下大致说明了我的应用程序现在是如何构建的:

abstract class AbstractService implements ObjectManagerAwareInterface
{

    private $objectManager;

    public function getObjectManager()
    {
        return $this->objectManager;
    }

    public function setObjectManager(ObjectManager $objectManager)
    {
        $this->objectManager = $objectManager;

        return $this;
    }

}

class MyService extends AbstractService
{

    public function doSomething()
    {
        $count = $this->someCalculation();
        $myForm = new MyForm($count, $this->getObjectManager());

        // ...
    }

}

class MyForm extends Form
{

    private $objectManager;

    public function __construct($count, ObjectManager $objectManager) // TODO: Remove $objectManager
    {
        parent::__construct('myForm');

        $this->objectManager = $objectManager;

        $myCollection = new Collection('myCollection');
        $myCollection->setCount($count);
        $myCollection->setTargetElement(new MyFieldset($objectManager)); // TODO: ???
        $myCollection->setUseAsBaseFieldset(true);
        $this->add($myCollection);

        $submit = new Submit('submit');
        $this->add($submit);
    }
}

abstract class AbstractFieldset extends Fieldset
                                implements ObjectManagerAwareInterface
{

    private $objectManager;

    public function getObjectManager()
    {
        return $this->objectManager;
    }

    public function setObjectManager(ObjectManager $objectManager)
    {
        $this->objectManager = $objectManager;

        return $this;
    }

}

class MyFieldset extends AbstractFieldset
{

    public function __construct(ObjectManager $objectManager) // TODO: Remove $objectManager
    {
        parent::__construct('myFieldset');

        $this->setObjectManager($objectManager); // TODO: Use initializer

        $this->setHydrator(new DoctrineObject($this->getObjectManager(), true));
        $this->setObject(new MyModel());

        // ...
    }
}

1 个答案:

答案 0 :(得分:3)

基本上你想要使用FormElementManager

// Config array
'form_elements' => [
    'factories' => [
        'My\Cool\Fieldset' => 'My\Cool\FieldsetFactory'
    ]
]

然后你有一个正常的工厂级

class FieldsetFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $sl)
    {
        $realServiceLocator = $sl->getServiceLocator();
        $entityManager      = realServiceLocator->get('Doctrine\ORM\EntityManager');

        return new \My\Cool\Fieldset($entityManager);
    }
}

这将是最合适的方式。