Короткий вопрос: как я могу внедрить EntityManager во встроенные типы форм в symfony2 3.0+? Примечание. Я упомянул встроенные типы форм, а не только родительскую.
Длинный вопрос:
В предыдущих версиях Symfony2 (<2.6) Я обнаружил, что мне нужно следующее: у меня есть сущность A, у которой есть сущность B, у которой есть сущность C, у каждой сущности есть своя собственная форма, и в каждом типе формы сущности у меня есть необходимость использовать диспетчер сущностей.
В предыдущих версиях я делал следующее в контроллере:
$em = $this->getDoctrine()->getManager();
$a = new A();
$form = $this->createForm(new AType($em), $a);
Затем в AType я смог использовать $ em в конструкторе и продолжить передавать его потомкам:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('b', new BType($this->em))
;
}
И в BType.php я бы сделал то же самое в buildForm, чтобы передать $ em в CType.
Проблема, с которой я сейчас сталкиваюсь, заключается в том, что для определения встроенных форм в symfony2 3.0+ вам нужно сделать что-то вроде этого:
$form = $this->createForm(AType::class, $a);
Делая это таким образом, не имея доступа к контроллеру, оставляю мне (насколько я знаю) только одну опцию, определяющую форму как службу. С этой опцией у меня есть 2 проблемы, одна из которых заключается в том, что, как они указывают в своей документации, это следует использовать, если форма будет использоваться в нескольких частях вашего приложения, в этом случае эта форма будет находиться только в одном разделе у приложения и у меня есть та ABC иерархия, чтобы иметь надлежащую структуру базы данных (что-то вроде Компании> Владелец> Сотрудник). Моя другая проблема заключается в том, что если я определю форму как службу, я осознаю, что могу использовать:
$form = $this->createForm('servicename', $a);
в контроллере, и это будет вводить EntityManager, но как насчет BType и CType, как я могу внедрить EntityManager в них, используя AType в качестве службы?
Моя последняя идея / попытка, которую я считаю очень уродливой, это определение A, B, C как сервиса и создание формы в контроллере.
Хорошо, я понял это с @Cerad
app.form.a:
class: AppBundle\Form\AType
arguments: ["@doctrine.orm.entity_manager"]
tags:
- { name: form.type, alias: app.form.a }
app.form.b:
class: AppBundle\Form\BType
arguments: ["@doctrine.orm.entity_manager"]
tags:
- { name: form.type, alias: app.form.b }
app.form.c:
class: AppBundle\Form\CType
arguments: ["@doctrine.orm.entity_manager"]
tags:
- { name: form.type, alias: app.form.c }
А потом в контроллере при звонке:
$form = $this->createForm(AType::class, $a);
Видимо Symfony2 в фоновом режиме ищет сервис и внедряет зависимости, я путаюсь с тем, что перед тем, как вам пришлось вызывать сервис самостоятельно при использовании createForm … я не видел никакой документации по этому поводу ..
Затем в типах, когда вы делаете:
private $em;
public function __construct(EntityManager $em)
{
$this->em = $em;
}
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('b', BType::class)
;
}
Symfony также позаботится о внедрении зависимостей BType, если вы определите его как сервис.
Спасибо @Cerad! Ваш комментарий заставил меня выполнить этот тест!
Других решений пока нет …