#native_company# #native_desc#

Use Dice for Simplified PHP Dependency Injection

By Tom Butler
on March 17, 2013

Dice is a Dependency Injection Container for PHP. It allows you to very quickly and simply use Dependency Injection techniques in your code with very minimal effort on your end. For example, with zero configuration, Dice can convert this:

 $a = new A(new B, new C, new D(new E, new F)); 

Into this:

 $dice = new Dice;
 $a = $dice->create('A'); 

It automatically resolves all the dependencies required by a given class and creates the object tree.

What makes Dice different?

Dice uses a rule-based approach to dependency resolution. Where other containers force you to create factories or methods for every potential object in the system that uses dependencies, Dice allows you to define rules such as “Any class which requests an instance of PDO will be given this instance” which are followed for any arbitrary class within the application.

Getting started with Dice

As a practical example, a very common shared dependency in PHP applications is a database object. For this demonstration I’ll use PDO.

Firstly, PDO would be defined within the container:

 $rule = new DiceRule
 //tell Dice that any object which follows this rule will be shared throughout the application
 $rule->shared = true; 
 //Anything that follows this rule will use these constructor arguments: 
 $rule->constructParams = array('mysql:host=;dbname=mydb', 'username', 'password'); 
 //Add the rule to the container and apply it to the PDO class or anything that inherits it
 $dice->addRule('PDO', $rule); 

Next, we need to define a class which asks for an instance of PDO in its constructor:

 class Blog {
      private $pdo; 
     public function __construct(PDO $pdo) {
     $this->pdo = $pdo; 

As you can see, the Blog class has a dependency on the PDO object. Dice can now be used to construct a Blog object which uses the shared instance of PDO.

 $blog = $dice->create('Blog'); 

Here, a blog object will be created by Dice and supplied with the shared PDO object as it’s constructed

It’s important to note that Dice doesn’t need to know anything at all about the Blog class. The first time it’s ever heard of it is when it’s been told to create it.

What’s more, Dice can handle unlimited levels of nesting:

 class Application {
      private $controller; 
     public function __construct(Controller $controller) {
      $this->controller = $controller; 
} class Controller {
      private $user; 
     private $blog; 
     public function __construct(Blog $blog, User $user) {
} class User {
      private $pdo; 
     public function __construct(PDO $pdo) {
      $this->pdo = $pdo; 
} $application = $dice->create('Application'); 

Here, both the Blog and User object get passed the shared instance of PDO as they’re created. The entire object tree is created automatically and the only class that Dice has been explicitly told anything about is PDO. It automatically works out exactly what dependencies are required by any class it creates and uses rules to work out where those dependencies come from.

What does this mean for you, the PHP developer?

It means you have unlimited flexibility in what dependencies your classes have and changing them at any point during the project lifecycle is a painless task. Let’s during development. The User object is given a dependency on a Session object as well as PDO:

 class User {
      private $pdo; 
     private $session; 
     public function __construct(PDO $pdo, Session $session) {
      $this->pdo = $pdo; 
     $this->session = $session; 

With Dice you don’t have to worry about how the User accesses the Session object, you add it as a constructor parameter and it Just works. You don’t need to reconfigure the container, you don’t need to do anything at all. You just alter the constructor definition and everything is done for you.

What this means is that during development you can add, remove and totally change all the dependencies of a given class without having to worry about knock on effects elsewhere in the system or having to reconfigure a Dependency Injection Container to account for the API change.

This has just been a taster but Dice offers a large amount of functionality to deal with any scenario you may have regarding dependencies in PHP. Hopefully this taster has been enough to tempt you to try Dice in your next project. You’ll wonder how you ever lived without it!

See the Dice home page for more examples and to download the script.

About the author

Tom Butler has been programming in PHP since 1999. His first paid PHP job was in 2004 while at University and after graduating in 2007 has been working as a full time PHP Developer since. Tom is best known in the PHP community for writing several highly referenced albeit slightly controversial articles on the subject of the use of the MVC architecture in PHP.