簡體   English   中英

無法自動裝配服務:參數引用 class 但不存在此類服務

[英]Cannot autowire service: Argument references class but no such service exists

我正在將一個項目從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)(內置:2017 年 12 月 7 日 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

從 1.8 版本的 DoctrineBundle 開始,你可以使用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 曾經。 您不希望存儲庫的接口具有createQueryflush類的方法。 至少,如果您將存儲庫視為對象的集合,那么您不希望這樣。 如果您擴展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.
}

不需要其他步驟。

我的問題是命名空間錯誤。 文件實際位置是App\\Infrastructure\\MySQL\\Rubric\\Specification但是命名空間被設置為App\\Infrastructure\\Rubric\\Specification

結果“[blah blah] 但不存在這樣的服務”。

我得到了這個問題。 我的服務有一個私有構造函數。 我不得不改變:

private function __construct(

public function __construct(

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM