Symfony 2 EntityManagerインジェクションインサービス


96

独自のサービスを作成し、Doctrine EntityManagerを挿入する必要がありますが、それが__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);

オブジェクト(nullではない)を取得しましたが$this->em、UserServiceがnullであり、すでに述べたように、UserServiceのコンストラクターは呼び出されていません

もう1つ、ControllerとUserServiceは異なるバンドルにあります(プロジェクトを整理しておくために本当に必要です)。

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

UserServiceを取得して有効な(nullではない)EntityManagerオブジェクトを取得するために使用するのと同じコントローラー内。

構成の一部またはUserServiceとDoctrine構成の間のリンクが欠落しているように見えます。


セッター注入を試しましたか?できます?
グレモ

「セッターインジェクション」とは、私のサービスでEntityManagerのセッターメソッドを追加し、パラメーターとして$ this-> get( 'doctrine.orm.entity_manager')を使用してコントローラーを呼び出すことを意味する場合、はい、私は試してみましたが機能します。しかし、私は本当に設定を介して適切な注入を使用するのが好きです
Andrey Zavarin

2
つまり、symfony.com / doc / current / book / とにかく__constructorエラーです。
gremo

ええと、私がセッター注入を試したことがないより。__constructは問題を修正しましたが、とにかく、あなたの助けをありがとう!
Andrey Zavarin

回答:


112

クラスのコンストラクタメソッドは__construct()、ではなくを呼び出す必要があります__constructor()

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

2
こんにちは、この例では、どのようにして接続をデフォルトから他の接続に変更できますか?
ptmr.io 2018

そうですが、インターフェースを使用するとさらに良いでしょう。public function __construct(EntityManagerInterface $entityManager)
Hugues D

65

最近の参考として、Symfony 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 / console container:debugまた、実行しているサービスも確認します。
Hard Fitness

18

Symfony 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は確かに減価償却されていません。インターフェイスの使用は自動配線に役立ち、推奨されますが、必須ではありません。そして、インターフェースは長い間存在しています。ここでは特に新しいことはありません。
Cerad

これが答えです。ただし、参照を行ってください。stackoverflow.com/questions/22154558/...
のTFont

私自身のソリューションに更新してください。適切な方法は、エンティティとリポジトリを使用することです。Entity Managerはすでに自然にリポジトリに注入されています。ここに例があります:youtu.be/AHVtOJDTx0M
Robert Saylor

7

2017年とsymfony 3.3ので、あなたができるサービスとしてリポジトリを登録することがあり、そのすべての利点と、。

より一般的な説明については私の投稿How to use Repository with Doctrine as Service in Symfonyチェックしてください


特定のケースでは、チューニングを含む元のコードは次のようになります。

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.