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)