プロジェクトをSymfony 3からSymfony 4(- https://github.com/symfony/symfony/blob/master/UPGRADE-4.0.md )そして、私はこのような多くのリポジトリ/サービスを持っています:
namespace App\Entity;
use App\Entity\Activation;
use Doctrine\ORM\EntityRepository;
use Predis\Client;
class ActivationRepository extends EntityRepository
{
// ...
}
そして、このようなブラウザでプロジェクトを実行しようとすると:
http://localhost:8000/login
私はこのエラーを受け取ります:
(1/1) RuntimeException
Cannot autowire service "App\Entity\ActivationRepository":
argument "$class" of method
"Doctrine\ORM\EntityRepository::__construct()"
references class "Doctrine\ORM\Mapping\ClassMetadata"
but no such service exists.
これは、services.yamlファイルで "Doctrine\ORM\Mapping\ClassMetadata"のサービスを作成する必要があるということですか?
自動配線のおかげで、新しいservices.yamlファイルは、2000行以上ある古いファイルに比べてかなり小さくなっています。新しいservices.yamlには、これらのいくつかが含まれています(これまで):
App\:
resource: '../src/*'
# Controllers
App\Controller\:
resource: '../src/Controller'
autowire: true
public: true
tags: ['controller.service_arguments']
# Models
App\Model\:
resource: '../src/Model/'
autowire: true
public: true
// etc
質問:サードパーティベンダークラスのサービス定義をservices.yamlに追加する必要が本当にありますか?もしそうなら、それを行う方法の例を入手できますか?すでにSymfony 3からSymfony 4にアップグレードした人からのアドバイス素晴らしいことだ。
PHP 7.2.0-2 + ubuntu16.04.1 + deb.sury.org + 2(cli)(built:Dec 7 2017 20:14:31)(NTS)Linux Mint 18、Apache2 Ubuntu。
編集/参考:
これは、ActivationRepositoryが拡張する「Doctrine\ORM\EntityRepository :: __ construct()」です。
/**
* Initializes a new <tt>EntityRepository</tt>.
*
* @param EntityManager $em The EntityManager to use.
* @param Mapping\ClassMetadata $class The class descriptor.
*/
public function __construct(EntityManagerInterface $em, Mapping\ClassMetadata $class)
{
$this->_entityName = $class->name;
$this->_em = $em;
$this->_class = $class;
}
ここにあります:
/vendor/doctrine/orm/lib/Doctrine/ORM/EntityRepository.php
DoctrineBundleの1.8バージョンから開始して、Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository
の代わりにDoctrine\ORM\EntityRepository
を使用してクラスを拡張できます。結果は同じになりますが、これは自動配線をサポートします。
例:
use App\Entity\Activation;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Common\Persistence\ManagerRegistry;
class ActivationRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Activation::class);
}
// ...
}
サードパーティベンダークラスのサービス定義をservices.yamlに追加する必要が本当にありますか?
いいえ、それをしないでください。私の個人的な提案は:EntityRepository
を拡張しないでください。今まで。リポジトリのインターフェースにcreateQuery
やflush
のようなメソッドを持たせたくない。少なくとも、オブジェクトのコレクションのようなリポジトリを検討する場合、それは望ましくありません。 EntityRepository
を拡張すると、漏れやすい抽象化になります。
代わりに、リポジトリ内にEntityManager
を挿入できます。それで終わりです。
use App\Entity\Activation;
use App\Repository\ActivationRepository;
use Doctrine\ORM\EntityManagerInterface;
final class DoctrineActivationRepository implements ActivationRepository
{
private $entityManager;
private $repository;
public function __construct(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
$this->repository = $this->entityManager->getRepository(Activation::class);
}
public function store(Activation $activation): void
{
$this->entityManager->persist($activation);
$this->entityManager->flush();
}
public function get($id): ?Activation
{
return $this->repository->find($id);
}
// other methods, that you defined in your repository's interface.
}
他の手順は必要ありません。