2016-04-23 11 views
2

Hallo Kurze Frage über Dependency InjectionPHP Dependency Injection und Vererbung

Ich verwende symfony 3 und komme sich mit DI

Sagen wir, ich habe eine Klasse

use Doctrine\ORM\EntityManagerInterface; 

class CommonRepository 
{ 
    /** 
    * @var EntityManagerInterface 
    */ 
    protected $em; 

    /** 
    * DoctrineUserRepository constructor. 
    * @param EntityManagerInterface $em 
    */ 
    public function __construct(EntityManagerInterface $em) 
    { 
     $this->em = $em; 
    } 
    public function getEntityManager() 
    { 
     return $this->em; 
    } 
} 

Jetzt eine neue Klasse namens UserRepository und ich injiziere die oben genannte Klasse, bedeutet das, dass ich auf die injizierten Items zugreifen kann (eindeutig hat er am Ende der Einführung geträumt)?

class UserRepository 
{ 
    /** 
    * @var CommonDoctrineRepository 
    */ 
    private $commonRepository; 

    /** 
    * @var \Doctrine\ORM\EntityManagerInterface 
    */ 
    private $em; 

    /** 
    * DoctrineUserRepository constructor. 
    * @param CommonRepository $CommonRepository 
    */ 
    public function __construct(CommonRepository $CommonRepository) 
    { 
     $this->commonRepository = $commonRepository; 
     $this->em = $this->commonRepository->getEntityManager(); 
    } 
    public function find($id) 
    { 
     //does not seem to work 
     //return $em->find($id); 
     //nor does 
     //return $this->em->find($id); 
    } 
} 

auch wenn ich die Klasse erweitern und dann versuchen, Eltern keine Freude zu konstruieren, klar kann ich spritzen nur die Lehre Manager in die UserRepository, ich habe nur versucht, ein gewisses Verständnis um DI zu erhalten und Erbe

class UserRepository extends CommonRepository 
{ 
    /** 
    * @var CommonDoctrineRepository 
    */ 
    private $commonRepository; 

    /** 
    * @var \Doctrine\ORM\EntityManagerInterface 
    */ 
    private $em; 

    public function __construct(CommonDoctrineRepository $commonRepository, $em) 
    { 
     parent::__construct($em); 
     $this->commonRepository = $commonRepository; 
    } 
} 

für die symfony Komponente I Dienste wie

app.repository.common_repository: 
    class: AppBundle\Repository\Doctrine\CommonRepository 
    arguments: 
     - "@doctrine.orm.entity_manager" 

app.repository.user_repository: 
    class: AppBundle\Repository\Doctrine\UserRepository 
    arguments: 
     - "@app.repository.common_repository"   

Antwort

3

Dependency Injection definiert haben, ist nur die Prozessobjekte der Übergang in der Konstruktor (oder Setter-Methoden). Ein Dependency Injection Container (oder Service Container) ist nichts anderes als ein Hilfsmittel, um die korrekten Instanzen von Objekten in den Konstruktor zu injizieren.

Mit diesem gesagt, ist es klar, dass Dependency Injection PHP in keiner Weise beeinflusst (übrigens, nichts in Symfony tut, es ist alles nur einfache PHP-Zeug).

So funktioniert Vererbung genau so, wie es mit einigen einfachen PHP-Objekten funktioniert (was eine seltsame Vergleich ist, da sie bereits einfache PHP-Objekte sind).

Das bedeutet, wenn CommonRepository#getEntityManager() öffentlich ist und die CommonRepository korrekt instanziiert wird, sollte diese Methode den Entity Manager zurückgeben, der an seinen Konstruktor übergeben wurde.

Gleiches gilt für UserRepository: Wenn Sie die übergebene CommonRepository#getEntityManager() Instanz im $em Eigenschaft speichern, werden alle Methoden der Entity-Manager mit dieser $em Eigenschaft zugreifen können. Dies bedeutet, $this->em->find(...) tun sollte perfekt funktionieren ($em->find(...) sollte nicht, da es keine $em Variable).

tl; dr: Der Code, den Sie in Ihrer Frage (außer dem seltsamen extence Beispiel) gezeigt haben, funktioniert tadellos.

+1

Dank Wouter, also wenn Sie etwas über den Konstruktor übergeben, können Sie auf alles von der Klasse zugreifen, die übergeben wird, einschließlich was auch immer es konstruiert? – hounded

+0

Ja, Sie sind richtig. –