Resolve the dependencies of our objects
We're going to use the Reflection API
We Instantiating an object with its dependencies :
<?php
class MainController {
/**
* @var UserRepository
*/
private $repository;
public function __construct(UserRepository $repository)
{
$this->repository = $repository;
}
}
class UserRepository {
/**
* @var Database
*/
private $database;
public function __construct(Database $database)
{
$this->database = $database;
}
}
class Database {
}
$controller = new MainController(new UserRepository(new Database()));
The dependencies has dependencies themselves and this can become unmanageable
The solution :
<?php
class ReflectionResolver
{
/**
* @param string $class
* @return object
* @throws \ReflectionException
*/
public function resolve(string $class): object
{
$reflectionClass = new \ReflectionClass($class);
if (($constructor = $reflectionClass->getConstructor()) === null) {
return $reflectionClass->newInstance();
}
if (($params = $constructor->getParameters()) === []) {
return $reflectionClass->newInstance();
}
$newInstanceParams = [];
foreach ($params as $param) {
$newInstanceParams[] = $param->getClass() === null ? $param->getDefaultValue() : $this->resolve(
$param->getClass()->getName()
);
}
return $reflectionClass->newInstanceArgs(
$newInstanceParams
);
}
}
How to use ?
<?php
$resolver = new ReflectionResolver();
$controller = $resolver->resolve(MainController::class)
var_dump($controller);
//object(MainController)[1]
// private 'repository' =>
// object(UserRepository)[2]
// private 'database' =>
// object(Database)[3]
Ideal for small project
Simple and easy!
Top comments (2)
Just be careful while using Reflection in production apps. It affects performance.
indeed it must be accompanied by a caching system.