2012-01-11 14 views
9

में श्रोता में डेटाबेस तक पहुंच हमें श्रोता में डेटाबेस जानकारी तक पहुंचने की आवश्यकता है। हम एक service.yml श्रोता में श्रोता कॉन्फ़िगर की तरह है:सिम्फनी 2

namespace company\MyBundle\Listener; 

use Symfony\Component\HttpKernel\Event\GetResponseEvent; 
use Symfony\Component\HttpKernel\HttpKernelInterface; 
use Symfony\Component\DependencyInjection\ContainerInterface; 
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 
use Symfony\Component\HttpFoundation\RedirectResponse; 
use Symfony\Bundle\FrameworkBundle\Controller\Controller; 

class RequestListener 
{ 
    protected $container; 

public function __construct(ContainerInterface $container) 
{ 
    $this->container = $container; 
} 

public function onKernelRequest(GetResponseEvent $event) 
{ 
... 

हम कैसे onKernelRequest समारोह में सिद्धांत को एक्सेस कर सकते हैं?

मैं नियंत्रक से फैली की कोशिश की और कार्य करें:

 $em = $this->getDoctrine()->getEntityManager(); 

और यह काम करता है, लेकिन मुझे लगता है कि यह एक बुरा व्यवहार है।

+0

सभी टिप्पणियों के लिए धन्यवाद। सभी अच्छे विकल्प हैं। – Santi

उत्तर

27

आप केवल सेवा कंटेनर इंजेक्ट कर सकते हैं। सबसे पहले एक EntityManager प्राप्त करने के लिए निर्माता को बदलने:

use Doctrine\ORM\EntityManager; 

class RequestListener { 
    protected $em; 
    function __construct(EntityManager $em) 
    { 
     $this->em = $em; 
    } 
    //... 
} 

और अगले कॉन्फ़िगर आपकी सेवा:

#... 
services: 
    foo.requestlistener: 
     class: %foo.requestlistener.class% 
     arguments: 
      - @doctrine.orm.entity_manager 
+0

धन्यवाद, एक अच्छा विकल्प – Santi

+3

यह सबसे अच्छा विकल्प है। –

+0

धन्यवाद जो मैंने एक बार काम किया "सिम्फनी \ घटक \ निर्भरता इंजेक्शन \ कंटेनर इंटरफेस का उपयोग करें;" – someuser

2

ऐसा लगता है आप श्रोता में सेवा कंटेनर इंजेक्शन लगाने रहे हैं, तो आप सिद्धांत इस तरह से उपयोग कर सकते हैं:

$doctrine = $this->container->get('doctrine'); 
1

मैं अभी भी Symfony एक नौसिखिया की तरह कर रहा हूँ, लेकिन आप गुजर की कोशिश की है doctrine सेवा कंटेनर के बजाय आपके श्रोता के लिए सेवा?

वैकल्पिक रूप से, आप पहले से ही सेवा कंटेनर पास कर रहे हैं, इसलिए यह
$this->container->get('doctrine') पर कॉल करने जितना सरल होना चाहिए। इसके अलावा, मुझे कुछ समय पहले आईआरसी में बताया गया था कि सेवा कंटेनर को गुजरना आमतौर पर खराब अभ्यास माना जाता है। आपको आवश्यक व्यक्तिगत सेवाओं को पार करना बेहतर है।

+0

धन्यवाद, एक अच्छा विकल्प है – Santi

0

मैं श्रोताओं के लिए व्यापार तर्क डाल नहीं होगा, क्योंकि केवल घटनाओं को सुनने के लिए कर रहे हैं। और आप सिद्धांत का उपयोग कर श्रोता के लिए परीक्षण कैसे लिखेंगे ...

मैं सिद्धांत को एक अलग वर्ग में सामग्री तक पहुंचने और फिर श्रोता में कॉल करने के लिए कहूंगा।

2

आपके उपयोग के मामले आप एक सिद्धांत घटना श्रोता directely

#services.yml 
qis.listener.contractBundleStatusListener: 
    class: Acme\AppBundle\EventListener\MyListener 
    tags: 
     - { name: doctrine.event_listener, event: postPersist } 

उपयोग करने के लिए आप LifecycleEventArgs से इकाई प्रबंधक प्राप्त कर सकते हैं अनुमति देता है:

<?php 

use Doctrine\ORM\Event\LifecycleEventArgs; 

class MyListener 
{ 
    public function postPersist(LifecycleEventArgs $args) 
    { 
     $entity = $args->getEntity(); 

     if ($entity instanceof Foo) { 
      $entityManager = $args->getEntityManager(); 

      $entityManager->persist($entity); 
      $entityManager->flush(); 
     } 
    } 
}