সিমফনি 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আমার অ্যাপ্লিকেশনটিতে। জিমটি আমদানি করেছি

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')

আমি একইভাবে ব্যবহারকারীর পরিষেবা পেতে এবং বৈধ (নাল নয়) সত্তাটি ম্যানেজার অবজেক্টটি পেতে ব্যবহার করি।

দেখে মনে হচ্ছে যে আমি কনফিগারেশনের টুকরো বা ইউজার সার্ভিস এবং ডক্ট্রাইন কনফিগারেশনের মধ্যে কিছু লিঙ্ক মিস করছি।


আপনি সেটার ইঞ্জেকশন চেষ্টা করেছেন? এটা কাজ করে?
গ্রেমো

যদি 'সেটার ইনজেকশন' দ্বারা আপনি বোঝাতে চাইছেন আমার পরিষেবাতে অ্যান্টি ম্যানেজারের জন্য সেটার পদ্ধতি যুক্ত করুন এবং প্যারামিটার হিসাবে $ this-> get ('doctrine.orm.entity_manager') দিয়ে নিয়ামককে কল করুন, তবে হ্যাঁ, আমি চেষ্টা করেছি এবং এটি কাজ করে। তবে আমি কনফিগারেশনের মাধ্যমে যথাযথ ইনজেকশনটি ব্যবহার করতে পছন্দ করি
আন্দ্রে জাভারিন

4
আমি এটি বোঝাতে চাইছি: symfony.com/doc/current/book/… যাই হোক __constructorত্রুটি।
গ্রেমো

হুম, আমি সেটার ইঞ্জেকশন চেষ্টা করিনি। __ কাঠামো সমস্যা সমাধান করেছে, তবে যাইহোক, আপনার সহায়তার জন্য আপনাকে ধন্যবাদ!
অ্যান্ড্রে জাভরিন

উত্তর:


112

আপনার শ্রেণীর নির্মাতা পদ্ধতি কল করা উচিত __construct(), না __constructor():

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

4
হাই, এই উদাহরণে, আমি কীভাবে সংযোগটি ডিফল্ট থেকে অন্য কোনওটিতে পরিবর্তন করতে পারি?
ptmr.io

ঠিক আছে, তবে আপনি যদি কোনও ইন্টারফেস ব্যবহার করেন তবে এটি আরও ভাল। public function __construct(EntityManagerInterface $entityManager)
হিউগস ডি

65

আধুনিক রেফারেন্সের জন্য, সিমফনি ২.৪++ তে আপনি কনস্ট্রাক্টর ইনজেকশন পদ্ধতির পক্ষে যুক্তির নাম রাখতে পারবেন না। ডকুমেন্টেশন অনুসারে আপনি পাস করতে হবে:

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

এবং তারপরে সেগুলি আর্গুমেন্টের মাধ্যমে তালিকাভুক্ত করা ক্রমে তারা উপলব্ধ থাকবে (যদি সেখানে 1 এর বেশি থাকে)।

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

8
আপনি এটি করতে পারেন: অ্যাপ / কনসোল ধারক: ডিবাগ এবং আপনি কী কী পরিষেবা চালাচ্ছেন তা সন্ধান করুন।
হার্ড ফিটনেস

18

সিমফনি ৩.৩ হিসাবে নোটটি সত্তা ম্যানেজার অবমূল্যায়ন করা হয়েছে। পরিবর্তে সত্ত্বা ম্যানেজারইন্টারফেস ব্যবহার করুন।

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;
        ...
    }
}

4
এই ক্ষেত্রে যদি কেউ হোঁচট খায় এবং বিভ্রান্ত হন: সত্তা ম্যানেজার অবশ্যই অবচয় করা হয়নি। ইন্টারফেসটি ব্যবহার করা অটো-ওয়্যারিংয়ের সাথে সহায়তা করে এবং এটি প্রস্তাবিত তবে কোনও প্রয়োজন নেই। এবং ইন্টারফেসটি দীর্ঘকাল ধরে ছিল। এখানে আসলে নতুন কিছু নেই।
সেরাদ

এই উত্তর। : তবে, রেফারেন্স দয়া করে stackoverflow.com/questions/22154558/...
tfont

আমার নিজের সমাধানে আপডেট করুন। সুনির্দিষ্ট উপায়টি হ'ল এজেন্সি এবং সংগ্রহস্থলগুলি ব্যবহার করা। সত্তা ব্যবস্থাপক ইতিমধ্যে স্বাভাবিকভাবেই একটি ভান্ডারটিতে ইনজেকশনের ব্যবস্থা করা হয়। আপনি এখানে একটি উদাহরণ দেখতে পারেন: 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
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.