Symfony 3 - Define form as a service
Defining a form type as service does not imply passing the instance retrieved from to container to createForm
. when doing this, the container is not involved as far as the form component is involved.
To use a form type registered as a service (with the form.type
tag so that the form component knows about it), you just just reference it by its name (i.e. the fully qualified class name in Symfony 2.8+ and the type name in older versions) in createForm
or in FormBuilder::add
.This is exactly what you do for Symfony core types btw (text
, choice
and so on), which are registered as services.the code of your controller does not change at all when using the form type as a service rather than having a form type without dependency and registered implicitly on first usage.
This is what i did to inject a form as a service in Symfony 3 from my Symfony 2 Code.
In my service.yml i changed
issue.form: class: Gutersohn\Bundle\CoreBundle\Form\IssueType arguments: ['@service_container'] tags: - { name: form.type, alias: issue }
to
issue.form: class: Gutersohn\Bundle\CoreBundle\Form\IssueType arguments: ['@service_container'] tags: - { name: form.type }
In my controller i changed
$form = $this->container->get('form.factory')->create($this->container->get('issue.form'), $issue, [ "method" => "post", "action" => $this->container->get('router')->generate("ticket_add")]);
to
$form = $this->container->get('form.factory')->create(IssueType::class, $issue, [ "method" => "post", "action" => $this->container->get('router')->generate("ticket_add")]);
In issue #17013 on GitHub, aliemre stated:
Adding form.type tag is enough in your service definition.
app.form.corporation_type: class: App\CorporationBundle\Form\CorporationType arguments: ["@doctrine.orm.entity_manager"] tags: - { name: form.type }
Controller should remain same:
$form = $this->createForm(CorporationType::class, $corporation);
I've tested and it works!