2017-08-17 46 views
3

我有一個由服務層和存儲庫層組成的應用程序。對於我已經聲明瞭接口的服務和存儲庫,我在控制器中注入了服務的接口,並且服務被注入了存儲庫的接口。這全部通過將autowire設置爲true來完成。使用Symfony3.3將存儲庫注入服務時出錯

當我在其中一個注入服務上調用一個方法時,它一切正常,只要我不調用需要注入存儲庫之一的函數。當我嘗試調用使用的倉庫,我得到以下錯誤的一個函數:

Cannot autowire service "AppBundle\Repository\TestRepository": argument "$em" of method "Doctrine\ORM\EntityRepository::__construct()" must have a type-hint or be given a value explicitly.

現在我想,這與事實,這與EntityRepository類從我的倉庫擴展到以做,因爲當我看着它看起來像這樣的構造:

class TestRepository extends EntityRepository implements TestRepositoryInterface 
 
{ 
 
public function __construct(
 
      EntityManager $em, 
 
      Mapping\ClassMetadata $class 
 
     ) { 
 
      parent::__construct($em, $class); 
 
     } 
 

 
    /** 
 
    * @return string 
 
    */ 
 
    public function getTest(): string 
 
    { 
 
     return 'This is a test'; 
 
    } 
 
}

其中明確包含在錯誤消息中提到的$ EM參數。我不知道如何解決這個問題。 目前我的服務和存儲庫在services.yml中配置相同,但由於服務似乎工作,我會認爲這不是問題。我是否需要爲我的存儲庫禁用autowire並在services.yml中手動配置它們,還是我錯過了一些非常明顯的東西?

回答

6

存儲庫不能直接實例化。您需要使用的EntityManager :: getRepository

所以,你需要在services.yml

// services.yml 
AppBundle\Repository\UserRepository: 
    factory: 'doctrine.orm.entity_manager:getRepository' 
    arguments: ['AppBundle\Entity\User'] 

然後自動裝配注射應努力來定義你的回購協議。

我會好奇的看看autowire是否真的能夠吸引人。它本質上令人沮喪,因爲有些服務如魔術般連線,而其他服務則需要人工干預,這可能會導致一些混亂。

+0

這確實是解決方案時,我直接從控制器調用庫。非常感謝。 – dvanmil

+0

這也適用於symfony4.0 – murtho

0

其實,有一種方法可以做到這一點,但我不知道,如果我們能/應該這樣做或不

class TestRepository extends EntityRepository 
{ 

    // Constructor for autowiring 
    public function __construct(EntityManager $em) 
    { 
     parent::__construct($em, $em->getClassMetadata(Test::class)); 
    }