Injecting Objects by Constructor with the Dependency Injection Pattern

While not being as widely known as other design patterns such as Factory, Singleton or Active Record, the Dependency Injection pattern provides both programmers and web developers with a well-structured solution that allows them to solve issues that arise when an object needs the functionality of another one (hence the dependency) to work as expected. This is the second part of a six-part series that shows you how to apply this pattern.

In simple terms, when this pattern is applied, the dependency is directly injected (hence its name), either through the constructor of the receiver object or via a setter method. In both cases, the implementation of the pattern goes hand in hand with a concept of software engineering called Inversion of Control. This concept states that the context in which an object exists is responsible for providing it with its dependencies, and not the inverse situation (the term “inversion” makes sense here).

Obviously, in a scenario where objects are merely passive entities that expect to receive the dependencies that they need to function properly from the outer world, putting injection dependency into practice is a no-brainer process. This is particularly true in the case of PHP 5 where its type hinting feature helps to achieve this task in a simple manner.

If you’ve already read the first part of this series, then you should have a vague idea of how to implement the dependency injection pattern in PHP 5. In that tutorial I developed a sample application composed of two building blocks: a rudimentary MySQL abstraction class, and a persistent class that required the functionality of the first for saving and retrieving its properties from a database table.

In this specific example, persistent objects were entirely responsible for creating the database handler that they needed to work, which happens to contradict the Inversion of Control principle. This is not a desirable effect.

Thus, in this second part of the series I’m going to discuss how to use the dependency injection pattern to solve the aforementioned issue. Now, it’s example time, so let’s move on and start writing some functional PHP 5 code!

{mospagebreak title=Review: inefficiently handling class dependencies} 

As I said at the beginning of this article, the sample MySQL-driven program developed in the preceding tutorial showed pretty clearly how to use the wrong approach to the dependency of a persistent class. In this particular example, the dependency in question was a basic database handler, which was created inside the constructor of the persistent class. This is definitely a very bad thing; this approach doesn’t stick to the schema imposed by the Inversion of Control principle referenced in the introduction.

Therefore, it’s important to spend a few minutes recalling how this sample application was built originally, so you can discover for yourself why the classes that compose this program establish a incorrect relationship with each other.

First off, here’s the definition of the database handler. Pay close attention to it:

class MySQL

{

private $result = NULL;

private $link = NULL;

private static $instance = NULL;

 

// returns a singleton instance of MySQL class (chainable)

public static function factory($host, $user, $password, $database)

{

if (self::$instance === NULL)

{

self::$instance = new MySQL($host, $user, $password, $database);

}

return self::$instance;

}

// connect to MySQL

public function __construct($host, $user, $password, $database)

{

if (FALSE === ($this->link = mysqli_connect($host, $user, $password, $database)))

{

throw new Exception(‘Error : ‘ . mysqli_connect_error());

}

}

 

// perform query

public function query($query)

{

if (is_string($query) AND empty($query) === FALSE)

{

if (FALSE === ($this->result = mysqli_query($this->link, $query)))

{

throw new Exception(‘Error performing query ‘ . $query . ‘ Error message :’ .mysqli_error($this->link));

}

}

}

 

// fetch row from result set

public function fetch()

{

if (FALSE === ($row = mysqli_fetch_assoc($this->result)))

{

mysqli_free_result($this->result);

return FALSE;

}

return $row;

}

 

// get insertion ID

public function getInsertID()

{

return mysqli_insert_id($this->link);

}

// count rows in result set

public function countRows()

{

if ($this->result !== NULL)

{

return mysqli_num_rows($this->result);

}

}

// implement destructor to close the database connection

function __destruct()

{

mysqli_close($this->link);

}

}

Obviously, the set of tasks performed by the above “MySQL” class are easy to follow. It allows you to run queries against a selected database, retrieve and count rows in a result set, and find insertion IDs. So far, there’s nothing special about the way that this abstraction class functions, right?

Moving on, below there’s the definition of the persistent class, which uses the previous database handler for saving and fetching its properties from a “users” MySQL table. Here’s how this class looks:

class User

{

private $data = array();

private $id = NULL;

private $db = NULL;

 

// constructor

public function __construct($id = NULL)

{

$this->db = MySQL::factory(‘host’, ‘user’, ‘password’, ‘database’);

if ($id !== NULL)

 {

$this->id = $id;

$this->db->query(‘SELECT * FROM users WHERE id=’ . $this->id);

$this->data = $this->db->fetch();

}

}

 

// set undeclared property

public function __set($property, $value)

{

if ($property !== ‘name’ and $property !== ‘email’)

{

return;

}

$this->data[$property] = $value;

}

 

// get undeclared property

public function __get($property)

{

if (isset($this->data[$property]) === TRUE)

{

return $this->data[$property];

}

}

 

// save object to session variable

public function __destruct()

{

if ($this->id === NULL)

{

$this->db->query("INSERT INTO users (id, name, email) VALUES (NULL, ‘$this->name’, ‘$this->email’)");

}

else

{

$this->db->query("UPDATE users SET name = ‘$this->name’, email = ‘$this->email’ WHERE id = $this->id");

 }

}

}

As seen above, there are no major complaints about the logic implemented by this class. It simply uses some magic methods provided by PHP 5 for making its own properties persist across multiple HTTP requests. The following script demonstrates how to accomplish this process in a friendly way:

// create a user object

$user1 = new User();

$user1->name = ‘Alejandro Gervasio’;

$user1->email = ‘alejandro@domain.com’;

 

// create another user object

$user2 = new User();

$user2->name = ‘Susan Norton’;

$user2->email = ‘susan@domain.com’;

Regardless of the fact that the “User” class does a decent job when it comes to building some persistent objects, it exposes a serious drawback. Yes, you guessed right! Its constructor is responsible for creating an instance of its dependency, that is a MySQL object, to have access to the storage table.

This is a poor approach where an object controls its context, when in reality the opposite should happen. So, how can this issue be addressed? Well, here’s where the dependency injection pattern comes in, since it’s possible to implement a version of it called “injection by constructor,” which allows you to apply the Inversion of Control principle very easily.

Want to see how this principle will be put to work with the two classes shown before? Then read the following segment. 

{mospagebreak title=Applying the Inversion of Control principle}

As I explained in the section that you just read, it’s extremely simple to invert the roles played by the classes that you saw before, thanks to the functionality given by dependency injection. In this particular case, I’m going to implement only a specific flavor of it, where the dependency of a class is passed in through a constructor.

To show you the benefits of dependency injection, the only thing that I’m going to do next is modify the constructor of the persistent “User” class, which now will look as follows:

class User

{

private $data = array();

private $id = NULL;

private $db = NULL;

 

// constructor

public function __construct(MySQL $db, $id = NULL)

{

$this->db = $db;

if ($id !== NULL)

{

$this->id = $id;

$this->db->query(‘SELECT * FROM users WHERE id=’ . $this->id);

$this->data = $this->db->fetch();

}

}

 

// set undeclared property

public function __set($property, $value)

{

if ($property !== ‘name’ and $property !== ‘email’)

{

return;

}

$this->data[$property] = $value;

}

 

// get undeclared property

public function __get($property)

{

if (isset($this->data[$property]) === TRUE)

{

return $this->data[$property];

}

}

 

// save object to session variable

public function __destruct()

{

if ($this->id === NULL)

{

$this->db->query("INSERT INTO users (id, name, email) VALUES (NULL, ‘$this->name’, ‘$this->email’)");

}

else

{

$this->db->query("UPDATE users SET name = ‘$this->name’, email = ‘$this->email’ WHERE id = $this->id");

}

}

}

Didn’t I tell you that implementing the dependency injection pattern was a simple process? Well, the tweaked definition of the “User” class proves that without a doubt. As you can see, now the class’s constructor is no longer responsible for creating an instance of the database handler; it simply takes it smoothly as an incoming argument.

It’s probable that you’ve already coded your classes that way, even without knowing that you were using the benefits of dependency injection. Now you know it, and you should feel proud of it.

Returning to the definition of the “User” class, since its dependency is passed to its internals via the constructor, the process, not surprisingly, is known as “dependency injection by constructor.” But there are other ways to achieve the same result. However, for the moment I’m going to explore only this introductory approach.

So far, so good. At this point, you’ve hopefully grasped the underlying logic of the dependency injection pattern, meaning that it’s time to see how the proper implementation of this pattern can improve the way that persistent objects are created.

Thus, in the last segment of this tutorial I’m going to set up a final example for you. It will show how the modified version of the “User” class will now behave much more efficiently when it comes to handling its dependency.

To see how this example will be developed, click on the link below and keep reading.

{mospagebreak title=The dependency injection pattern in action}

As I anticipated in the previous segment, the only thing that remains undone here is building a script that shows how to create a couple of persisting objects, after improving the definition of the originating class.

With that idea in mind, I wrote that script, and it appears below. Take a look at the following fragment, please:

// example of dependency injection via the constructor

// create instance of MySQL class

$db = new MySQL(‘host’, ‘user’, ‘password’, ‘database’);

// create first user object

$user1 = new User($db);

$user1->name = ‘Alejandro Gervasio’;

$user1->email = ‘alejandro@domain.com’;

 

// create second user object

$user2 = new User($db);

$user2->name = ‘Mary Smith’;

$user2->email = ‘mary@domain.com’;

Simple to code and read, isn’t it? Quite possibly, the previous script isn’t going to change the way that you develop your PHP 5 applications forever, but it shows in a nutshell how beneficial dependency injection can be when it comes to building programs where the context is responsible for providing the required dependencies to its objects, and not the opposite.

And with last code sample, I’m finishing this second episode of the series on applying the Dependency Injection pattern in PHP 5. As usual, feel free to edit all of the examples included in this tutorial, so you can develop a better understanding on this rather overlooked pattern.

Final thoughts

Over this second part of the series, you learned how to implement a specific version of the dependency injection pattern, commonly called “injection by constructor.” As its name suggests, this approach injects the dependency directly through the constructor of the receiver object. It’s just that simple.

In the next installment, I’m going to teach you how to apply the Dependency Injection pattern in its other flavor, which simply passes the corresponding dependency via a setter method.

Don’t miss the upcoming part!

[gp-comments width="770" linklove="off" ]
antalya escort bayan antalya escort bayan