Как правильно внедрить ObjectManager в наборы полей?

Я борюсь с правильной инъекцией ObjectManager Doctrine в мои наборы полей. Я не хочу передавать им все конструкторы. Дело в следующем:

Контроллеры:

  • Контроллеры не имеют ObjectManager.
  • Контроллеры используют службы.

Услуги:

  • Службы реализуют интерфейс ObjectManagerAwareInterface.
  • Службы получают ObjectManager с помощью класса Initializer.
  • Службы предоставляют Формы.

Формы:

  • У форм не должно быть ObjectManager — по крайней мере, пока он им не нужен.
  • Формы создают соответствующие наборы полей.

Наборы полей:

  • Наборы полей реализуют интерфейс ObjectManagerAwareInterface.

Как и сейчас, я передаю ObjectManager из службы через форму в набор полей. Такой подход очень некрасивый.

Я знаю, что есть решение с использованием FormElementManager. Но для этого мне нужно было бы предоставить Form доступ к ServiceLocator, внедрив его. Этот подход кажется не более правильным, чем мой текущий.

Вопрос заключается в том, как внедрить ObjectManager Doctrine в мои наборы полей, не внедряя глобальный ServiceLocator (или что-то еще) в мои формы. Я хотел бы оставить Формы простыми, если это возможно.

Ниже показано примерно, как мое приложение построено прямо сейчас:

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());

        // ...
    }
}

person Karsten    schedule 27.04.2014    source источник


Ответы (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);
    }
}

Это был бы самый правильный способ сделать это.

person Sam    schedule 27.04.2014
comment
+1 Я бы добавил, что набор полей, если он добавлен через $this->add() в форму, имеет доступ к FormElementManager через FormFactory (поэтому нет необходимости вводить локатор службы) - person AlexP; 28.04.2014