सेवा में सिम्फनी 2 एंटिटी मैनजर इंजेक्शन


96

मैंने अपनी स्वयं की सेवा बनाई है और मुझे डॉक्टिन एंटिटी मैनजर को इंजेक्ट करने की आवश्यकता है, लेकिन मुझे नहीं लगता कि __construct()इसे मेरी सेवा में कहा जाता है, और इंजेक्शन भी काम करता है।

यहाँ कोड और विन्यास है:

<?php

namespace Test\CommonBundle\Services;
use Doctrine\ORM\EntityManager;

class UserService {

    /**
     *
     * @var EntityManager 
     */
    protected $em;

    public function __constructor(EntityManager $entityManager)
    {
        var_dump($entityManager);
        exit(); // I've never saw it happen, looks like constructor never called
        $this->em = $entityManager;
    }

    public function getUser($userId){
       var_dump($this->em ); // outputs null  
    }

}

यहाँ services.ymlमेरे बंडल में है

services:
  test.common.userservice:
    class:  Test\CommonBundle\Services\UserService
    arguments: 
        entityManager: "@doctrine.orm.entity_manager"

मैंने config.ymlअपने ऐप्लिकेशन में .yml को उसी तरह आयात किया है

imports:
    # a few lines skipped, not relevant here, i think
    - { resource: "@TestCommonBundle/Resources/config/services.yml" }

और जब मैं नियंत्रक में सेवा को कॉल करता हूं

    $userservice = $this->get('test.common.userservice');
    $userservice->getUser(123);

मुझे एक ऑब्जेक्ट मिलता है (शून्य नहीं), लेकिन $this->emउपयोगकर्ता सेवा में शून्य है, और जैसा कि मैंने पहले ही उल्लेख किया है, उपयोगकर्ता सेवा पर निर्माता को कभी नहीं बुलाया गया है

एक और बात, नियंत्रक और उपयोगकर्ता सेवा अलग-अलग बंडलों में हैं (मुझे परियोजना को व्यवस्थित रखने के लिए वास्तव में आवश्यकता है), लेकिन फिर भी: हर और ठीक काम करता है, मैं कॉल भी कर सकता हूं

$this->get('doctrine.orm.entity_manager')

उसी नियंत्रक में जिसका उपयोग मैं UserService पाने के लिए और वैध (शून्य नहीं) EntityManager ऑब्जेक्ट प्राप्त करने के लिए करता हूं।

इस तरह देखें कि मैं कॉन्फ़िगरेशन का टुकड़ा या उपयोगकर्ता सेवा और सिद्धांत विन्यास के बीच कुछ लिंक गायब कर रहा हूं।


क्या आपने सेटर इंजेक्शन की कोशिश की है? यह काम करता हैं?
ग्रेमो

यदि 'सेटर इंजेक्शन' से आपका मतलब है कि मेरी सेवा पर एंटिटीमैनगर के लिए सेटर पद्धति में जोड़ें और नियंत्रक के रूप में इस $ के साथ कॉल करें-> ('doctrine.orm.entity_manager') पैरामीटर के रूप में, तो हाँ, मैंने कोशिश की है और यह काम करता है। लेकिन मैं वास्तव में विन्यास के माध्यम से उचित इंजेक्शन का उपयोग करना पसंद करता
हूं

2
मेरा मतलब यह है: symfony.com/doc/current/book/… फिर भी __constructorत्रुटि है।
ग्रीमो

उम, की तुलना में मैं सेटर इंजेक्शन की कोशिश नहीं की है। __construct ने समस्या को ठीक कर दिया, लेकिन वैसे भी, आपकी मदद के लिए धन्यवाद!
एंड्री ज़ावरिन

जवाबों:


112

आपकी कक्षा की निर्माण विधि को बुलाया जाना चाहिए __construct(), न कि __constructor():

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

2
नमस्ते, इस उदाहरण में, मैं डिफ़ॉल्ट से किसी अन्य में कनेक्शन कैसे बदल सकता हूं?
ptmr.io

सही है, लेकिन यह बेहतर होगा यदि आप एक इंटरफ़ेस का उपयोग करते हैं। public function __construct(EntityManagerInterface $entityManager)
ह्यूजेस डी

65

आधुनिक संदर्भ के लिए, सिम्फनी 2.4+ में, आप कंस्ट्रक्टर इंजेक्शन विधि के लिए तर्कों का नाम नहीं दे सकते। दस्तावेज़ के अनुसार आप इसमें पास होंगे:

services:
    test.common.userservice:
        class:  Test\CommonBundle\Services\UserService
        arguments: [ "@doctrine.orm.entity_manager" ]

और फिर वे उस क्रम में उपलब्ध होंगे जो उन्हें तर्कों के माध्यम से सूचीबद्ध किया गया था (यदि 1 से अधिक हैं)।

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

8
आप एक: app / कंसोल कंटेनर: डिबग कर सकते हैं और पता लगा सकते हैं कि आप किन सेवाओं को चला रहे हैं।
हार्ड फिटनेस

18

सिम्फनी 3.3 EntityManager के रूप में नोट मूल्यह्रास किया गया है। इसके बजाय EntityManagerInterface का उपयोग करें।

namespace AppBundle\Service;

use Doctrine\ORM\EntityManagerInterface;

class Someclass {
    protected $em;

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

    public function somefunction() {
        $em = $this->em;
        ...
    }
}

1
बस अगर किसी को इस पार ठोकर खाते हैं और उलझन में है: EntityManager निश्चित रूप से मूल्यह्रास नहीं किया गया है। इंटरफ़ेस का उपयोग करना ऑटो-वायरिंग के साथ मदद करता है और इसकी सिफारिश की जाती है लेकिन किसी भी तरह की आवश्यकता नहीं है। और इंटरफ़ेस लंबे समय से आसपास है। यहां वास्तव में कुछ भी नया नहीं है।
22

यह उत्तर है। हालाँकि, कृपया संदर्भ करें: stackoverflow.com/questions/22154558/…
tfont

मेरे अपने समाधान के लिए अद्यतन करें। उचित तरीका अब Entities और Repositories का उपयोग करना चाहिए। इकाई प्रबंधक पहले से ही स्वाभाविक रूप से एक भंडार में इंजेक्ट किया जाता है। आप यहां एक उदाहरण देख सकते हैं: youtu.be/AHVtOJDTx0M
रॉबर्ट सेलर

7

2017 और सिम्फनी 3.3 के बाद से आप रिपोजिटरी को सेवा के रूप में पंजीकृत कर सकते हैं , इसके सभी फायदे इसके पास हैं।

अधिक सामान्य विवरण के लिए सिम्फनी में सेवा के रूप में डॉक्ट्रिन के साथ रिपॉजिटरी का उपयोग कैसे करें, मेरी पोस्ट देखें


आपके विशिष्ट मामले के लिए, ट्यूनिंग के साथ मूल कोड इस तरह दिखेगा:

1. अपनी सेवाओं या नियंत्रक में उपयोग करें

<?php

namespace Test\CommonBundle\Services;

use Doctrine\ORM\EntityManagerInterface;

class UserService
{
    private $userRepository;

    // use custom repository over direct use of EntityManager
    // see step 2
    public function __constructor(UserRepository $userRepository)
    {
        $this->userRepository = $userRepository;
    }

    public function getUser($userId)
    {
        return $this->userRepository->find($userId);
    }
}

2. नया कस्टम रिपॉजिटरी बनाएं

<?php

namespace Test\CommonBundle\Repository;

use Doctrine\ORM\EntityManagerInterface;

class UserRepository
{
    private $repository;

    public function __construct(EntityManagerInterface $entityManager)
    {
        $this->repository = $entityManager->getRepository(UserEntity::class);
    }

    public function find($userId)
    {
        return  $this->repository->find($userId);
    }
}

3. सेवाओं को पंजीकृत करें

# app/config/services.yml
services:
    _defaults:
        autowire: true

    Test\CommonBundle\:
       resource: ../../Test/CommonBundle
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.