2016-09-01 7 views
0

Ich habe eine EventSubscriber getan, aber ich brauche EntityManager in verwenden, ich habe die services.yml wie diese gefüllt.Inject EntityManager in einem EventSubscriberInterface

app.subscriber.tube_dynamic_field: 
    class: AppBundle\Form\EventListener\TubeDynamicFieldSubscriber 
    arguments: ["@doctrine.orm.entity_manager"] 

Ich versuche, es zu benutzen, in den EventSubscriber wie dies:

class TubeDynamicFieldSubscriber implements EventSubscriberInterface 
{ 
    private $em; 

    public function __construct(EntityManager $em) 
    { 
     $this->em = $em; 
    } 

    ... 
} 

Schließlich verwende ich die EventSubscriber in einem Formtype wie folgt aus:

class TubeType extends AbstractType 
{ 
    private $dynamicFieldSubscriber; 

    public function __construct(TubeDynamicFieldSubscriber $subscriber) 
    { 
     $this->dynamicFieldSubscriber = $suscriber; 
    } 

    /** 
    * @param FormBuilderInterface $builder 
    * @param array $options 
    */ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder->addEventSubscriber($this->dynamicFieldSubscriber); 
    } 

... 
} 

Aber Ich habe einen Fehler:

Type error: Argument 1 passed to AppBundle\Form\TubeType::__construct() 
must be an instance of AppBundle\Form\EventListener 
\TubeDynamicFieldSubscriber, none given 

Ich habe versuchen, es zu benutzen: $builder->addEventSubscriber(new TubeDynamicFieldSuscriber()) aber ich habe wieder einen Fehler: Es ist nicht die EntityManager genesen.

Wenn Sie wissen, wie ich den EntityManager in den EventSubscriber injizieren kann :) Vielen Dank.

+0

Können Sie die Klassennamen in Ihre Code-Snippets aufnehmen? – Gerry

+0

um das SOLID-Prinzip zu respektieren, sollten Sie "auf eine Schnittstelle programmieren, keine Implementierung": Ich würde empfehlen, den FormType-Konstruktor zu ändern: 'public function __construct (EventSubscriberInterface $ suscriber) $ $ this-> dynamicField = $ Abonnent; } 'so Ihre Klasse ist nicht eng an Ihren Abonnenten gekoppelt, und Sie können leicht zu einem anderen Abonnenten austauschen – VaN

+0

Ich habe meine Nachricht bearbeitet und Klassennamen enthalten. Okay, für das SOLID-Prinzip gehe ich es lesen. Ich beginne gerade mit Symfony und PHP. Vielen Dank. – mpiot

Antwort

2

Während Ihre Code-Snippets nicht sehr klar sind, muss Ihr Formulartyp Abhängigkeiten aufweisen, die im Service-Container registriert werden müssen, damit Symfony (und die Formularfactory) wissen, wie er sie erstellt.

services: 
    my_form_type: 
     class: AppBundle\Form\TubeType 
     arguments: ["@my_event_subscriber"] 
     tags: [{ name: form.type }] 

jedoch ein besserer Weg, dies zu tun, ist wahrscheinlich den Entity-Manager in Form Typ zu injizieren:

services: 
    my_form_type: 
     class: AppBundle\Form\TubeType 
     arguments: ["@doctrine.orm.entity_manager"] 
     tags: [{ name: form.type }] 

diese Weise in Ihrem Code, können Sie einfach tun:

$builder->addEventSubscriber(new TubeDynamicFieldSuscriber($this->manager)); 
+0

Ich denke, der zweite Weg ist schlimmer als der erste. Der beste Weg ist, deine TubeType-Klasse eindeutig als Dienst zu registrieren, dem Tag ein Alias ​​zu geben (dasselbe wie der zurückgegebene Wert deiner TubeType: getName() -Methode) und dann dieses Formular mit seinem Alias ​​'$ form = $ zu laden this-> createForm ('app.forms.tube_type', new Tube()); 'siehe http://symfony.com/doc/current/form/create_custom_field_type.html#creating-your-field-type-as-a -service – VaN

+0

Aliasnamen für Formulartypen sind in Symfony 2.8 veraltet und werden in Symfony 3 entfernt. – Gerry

+0

dann laden Sie sie einfach als Standarddienst, '$ form = $ this-> createForm ($ this-> container-> get ('app.forms .tube_type '), new Tube()); ' – VaN