【问题标题】:How to properly inject the ObjectManager into Fieldsets?如何正确地将 ObjectManager 注入 Fieldsets?
【发布时间】:2014-06-12 19:58:09
【问题描述】:

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

控制器:

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

服务:

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

表格:

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

字段集:

  • 字段集实现 ObjectManagerAwareInterface。

现在我将ObjectManager 服务通过表单传递到字段集。这种做法很丑。

我知道有一个使用 FormElementManager 的解决方案。但为了做到这一点,我必须通过注入它来授予 Form 对 ServiceLocator 的访问权限。这种方法似乎并不比我目前的方法更合适。

问题是如何将 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());

        // ...
    }
}

【问题讨论】:

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


    【解决方案1】:

    基本上你想使用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);
        }
    }
    

    这将是最合适的方式。

    【讨论】:

    • +1 我要补充一点,如果在表单中通过$this->add() 添加该字段集,则可以通过FormFactory 访问FormElementManager(因此无需注入服务定位器)
    猜你喜欢
    • 2021-05-20
    • 1970-01-01
    • 2019-07-14
    • 2019-08-30
    • 1970-01-01
    • 2014-04-19
    • 1970-01-01
    • 2019-06-04
    • 2017-07-25
    相关资源
    最近更新 更多