di52 automagical powers in the work

Adding auto-magical dependency resolution powers to the PHP 5.2 compatible DI container.

New dog, old bone, new tricks

While PHP 5.2 is deprecated it’s still listed among the minimum requirements for WordPress. But PHP has progressed very much and with its techniques and tools. Part as an experiment and part out of need I’ve developed di52: a PHP 5.2 compatible dependency injection container. The last line in the README file says

The container will not guess dependencies, will not handle circular references and will not, in general, make anything smart. Yet.

And that’s currently true.

Guess what

Dependency guessing means that that DI container should read a class __construct method signature and automagically instantiate and inject what the class constructor requires. A code example

class MyClass { public function __construct(ConcreteClassOne $one, ConcreteClassTwo $two, $parameter = 23 ){ // whatever } }

Looking, and longing, Laravel IOC container docs the following would be possible using its IOC container:

$myClass = App::make(‘MyClass’);

and that’s it: $myClass is now a ready to run object instance. But I might be a better developer and typehint interfaces in place of concrete classes: in that case the container will need a little help knowing which concrete implementation should be used for which interface.

class MyClass { public function __construct(InterfaceOne $one, InterfaceTwo $two, $parameter = 23 ){ // whatever } }

App::bind(‘InterfaceOne’, ‘ClassOne’); App::bind(‘InterfaceTwo’, ‘ClassTwo’);

$myClass = App::make(‘MyClass’);

What happens under the hood is that the container will read the __construct method signature, take note of what it needs and instantiate what is needed for the class constructor to run; the $parameter argument will be set to its default value. That and much more recursively. This means the container will have no problem with this

class ClassOne { public function __construct(InterfaceThree $three, $parameter = ‘foo’){ // whatever } }

class MyClass { public function __construct(InterfaceOne $one, InterfaceTwo $two, $parameter = 23 ){ // whatever } }

App::bind(‘InterfaceOne’, ‘ClassOne’); App::bind(‘InterfaceTwo’, ‘ClassTwo’); App::singleton(‘InterfaceThree’, ‘ClassThree’);

$myClass = App::make(‘MyClass’);

Joy. Pure joy. All of this but out of my PHP 5.2 powered grasp.

Good lead

While I was working with the current implementation of di52 I’ve stumbled upon this article and found it inspiring. To the point where I’m developing a modification to di52 that will allow me to write this

$container = new tad_DI52_Container();

$container->bind(‘InterfaceOne’, ‘ClassOne’); $container->bind(‘InterfaceTwo’, ‘ClassTwo’); $container->singleton(‘InterfaceThree’, ‘ClassThree’);

$myClass = $container->make(‘MyClass’);

And be able to change that last line to

The container will try to help, be smart and resolve dependencies automatically provided some implementation details.