DEV Community

Cover image for automatic dependency injection in 4/5 lines of code
Simone Gentili
Simone Gentili

Posted on

automatic dependency injection in 4/5 lines of code

The project

You can find the code here.

Prerequisite

You just have installed composer due to this script uses psr-4 autoloading.

Usage

If you have a more complex situation like this

class Foo {}
class Bar { public function __construct(Foo $foo) {} }
class Pub {
  public function __construct(Bar $bar) {}
  public function method() {
    return 42;
  }
}
class Animal { }
class Cat { public function __construct(Animal $animal) {} }
class Fizz {
  public function __construct(private Pub $pub) {}
  public function doSomething(Cat $cat) {
    return $this->pub->method();
  }
}
Enter fullscreen mode Exit fullscreen mode

You can instance Fizz object and the run doSomething method just doing

$result = injector(Fizz::class, 'doSomething');
Enter fullscreen mode Exit fullscreen mode

5 line solution

This solution is not readable. Is just to create a clickbait.

function injector($instance, $method = '__construct', $deps = []) {
    foreach ((new \ReflectionMethod($instance, $method))->getParameters() as $dep) {
        $className = (string) $dep->getType();
        $deps[] = new $className;
    }
    return $method == '__construct' ? new $instance(...$deps) : injector($instance)->$method(...$deps);
}
Enter fullscreen mode Exit fullscreen mode

Readable solution

This is a readable solution.

function buildDeps($instance, $method, $deps = []) {
    $params = (new \ReflectionMethod($instance, $method))
        ->getParameters();
    foreach ($params as $dep) {
        $className = (string) $dep->getType();
        $deps[] = new $className;
    }
    return $deps;
}

function injector($instance, $method = '__construct') {
    $deps = buildDeps($instance, $method);
    return $method == '__construct'
        ? new $instance(...$deps)
        : injector($instance)->$method(...$deps);
}
Enter fullscreen mode Exit fullscreen mode

And if you want to see the entire process of its creation (but, sorry, only in italian) click here.

Top comments (0)