Search code examples
phpdomain-driven-designrepository-patternentities

How to do Dependency Injection of entities into a repository if those entities have required arguments for construction?


How do I do Dependency Injection of entities into a repository if those entities have required arguments for construction?

Take this simple example (in PHP, but question is language agnostic):

Person Entity

class Person
{
    private $firstName = "";
    private $middleName = "";
    private $lastName = "";
    private $dateOfBirth;
    private $dateOfDeath;

    public function __construct($firstName, $middleName = "", $lastName)
    {
        $this->firstName = $firstName;
        $this->middleName = $middleName;
        $this->lastName = $lastName;

        // Validation
        if(empty($this->firstName) || empty($this->lastName){
            throw new Exception("first and last name required");
        }
    }

    // ...
}

Person Repository

class PersonRepository
{
    public function __construct(Person $person)  // <-- problem, need required arguments
    {
         $this->person = $person;
    }

    public function fetchById($id)
    {
         // Query database
         // ...

         // Hydrate and return a person object
         // ...

         return $person;
    }

    // ...
}

So what am I missing? What is the standard approach to inject the entity and avoid using the new operator in the repository?


Solution

  • Read about "Abstract Factory". It's a pattern.

    class PersonRepository
    {
        public function __construct(PersonFactory $factory){
             $this->personFactory = $factory;
        }
    
        public function getById($id)
        {
             // ...
             return $this->personFactory->create($row['name'], $row['surname'], ...);
        }
    }