Beamtic's logo

Share via:

PHP: Dependency Injection (DI)

Article on why Dependency Injection and composition is better than inheritance and family trees.

56 views

Edited: 2020-09-06 09:56

Dependency Injection (DI) refers to the practice of passing on dependencies to classes that need them through the __construct method — also known as composition — it is generally a more flexible approach than relying on inheritance.

When employing inheritance to design an application, the problem usually is that classes will be very tightly coupled, and we will not be able to easily re-use a given part of the application in another context. If we rely on composition instead, however, then we can easily pick and choose the parts that we need for another project.

It also offers benefits when not planning to distribute or re-use code outside of the project, since we can more adequately organize our code into small, self-contained, objects with dependencies.

Composition over inheritance

Dependency injection is related to the design principle known as composition over inheritance When using inheritance, we design our applications around what they are; but when using composition, we design them around what they do. The beauty of compositing is that we do not have to refactor our entire application if we change the functionality later down the road.

For example, with inheritance, we would be extending a parent class to add functionality; but, this also means that we are now forced to instantiate the object from the child class. We can probably still instantiate the parent as a stand-alone class, but we will not be able to instantiate the child class without also instantiating the parent. Another problem with this configuration is that if something in the application changes, we might be forced to re-organize the entire class family tree.

If we use composition and dependency injection instead, then we can easily switch or remove dependencies. For example, if suddenly a class no longer needs a dependency, all we have to do is to remove it from the __construct method and refactor the class as needed. If we had instead relied on inheritance, then we would potentially be forced to change all of the classes in the entire family tree.

Inheritance might still be useful for very specific things, so this does not mean that we should completely ignore it and just use DI for everything; but composition does offer clear benefits, and by using it properly, we can avoid cornering ourselves into refactoring hell.

Composition root

When we use composition with dependency injection, we must have a place where we can instantiate the various objects that our application needs. For all intends and purposes, this is usually the index.php file (or whatever you have chosen to name it in your case).

But, it might also depend on the code library or framework that you are using. For example, there can indeed be multiple composition roots. A framework might have its own "composition root" where it "assembles itself", while it might offer a different place for developers to assemble their own code and interact with the framework.

In the case of a framework, a good example would be when having a router, also known as a url-mapper, that "maps" certain request paths to specific files or "composition roots" where a developer can then place code to handle HTTP requests. In this case, the framework will call the developers code depending on the URL (path) that was requested.

Note. A path must not be empty, so there should always, at least, be a forward slash "/" in the path of a request. It is possible to send a malformed HTTP request without path, but it should result in a error like 400 Bad Request or similar.

Comments

  1. How to create a custom error handler for PHP that handles non-fetal errors.
  2. We can access other classes properties (variables) and methods (functions) by injecting the class object in the class that needs it.
  3. Setting custom HTTP Headers with cURL is useful when changing User Agent or Cookies. Headers can be changed two ways, both using the curl_setopt function.
  4. Should you use file_get_contnts or cURL when performing HTTP requests from PHP? It does not matter; but regardless of which you use, you should still handle errors properly!
  5. When using file_get_contents to perform HTTP requests, the server response headers is stored in a reserved variable after each successful request; we can iterate over this when we need to access individual response headers.

More in: PHP Tutorials