hounded
hounded

Reputation: 726

PHP Dependency injection and Inheritance

Hi Quick question about dependency injection

I'm using symfony 3 and am coming to terms with DI

Say I have a class

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;
    }
}

Now a new class called UserRepository and I inject the above class, does that mean I can access the injected items injected items (clearly he was dreaming at the end of inception)?

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);
    }
}

even if I extend the class and then try to construct parent no joy, clearly I can just inject the Doctrine manager into the UserRepository, I was just trying to get some understanding around DI and inheritance

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;
    }
}

for the symfony component I have defined services like

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"           

Upvotes: 2

Views: 2260

Answers (1)

Wouter J
Wouter J

Reputation: 41934

Dependency Injection is just the process of passing objects into the constructor (or setter methods). A Dependency Injection Container (or Service Container) is nothing more but a helper to inject the correct instances of objects into the constructor.

With that said, it's clear that Dependency Injection doesn't influence PHP in any way (btw, nothing in Symfony does, it's all just plain PHP stuff).

So inheritance works just as it works with some plain PHP objects (which is a strange comparisation, as they already are plain PHP objects).

This means that if CommonRepository#getEntityManager() is public and the CommonRepository is instantiated correctly, this method should return the entity manager that was passed to its constructor.

The same applies to UserRepository: If you save the passed CommonRepository#getEntityManager() instance in the $em property, all methods can access the entity manager using this $em property. This means doing $this->em->find(...) should perfectly work ($em->find(...) shouldn't, as there is no $em variable).

tl;dr: The code you showed in your question (except from the weird extence example) works perfectly.

Upvotes: 5

Related Questions