Hello,
I wanted to come back to a mechanism that you will often encounter when you develop in oop, the dependency injection.
This technique not only ensures better readability but also better maintenance.
There are several types of dependency injections, we will detail the main ones:
- Injection by contructor
- Injection by mutator
- Injection by interface
- ...
Imagine, we want to associate a Post
class with the Author
class:
Without any dependency injection
class Post {
public function __construct($fullname, $website, $email) {
$this->setFullname($fullname);
$this->setWebsite($website);
$this->setEmail($email);
}
public function setFullname($fullname) {
$this->fullname = $fullname;
}
public function setWebsite($website) {
$this->website = $website;
}
public function setEmail($email) {
$this->email = $email;
}
}
We find that the two classes are intimately linked. For each field addition in the Author
class, we need to adjust the Post
constructor!
Let's see how to do with dependency injection:
Injection by contructor
use Author;
class Post {
public function __construct(Author $author) {
$this->setAuthor($author);
}
public function setAuthor(Author $author) {
$this->author = $author;
}
public function getAuthor() {
return $this->author;
}
}
You must instantiate an instance of the Author
class before instantiating the Post
class.
Injection by mutator
use Author;
class Post {
public function __construct() {
}
public function setAuthor(Author $author) {
$this->author = $author;
}
public function getAuthor() {
return $this->author;
}
}
Here, we must use the mutator to associate classes.
Injection by interface
interface AuthorInterface {
public function getFullname();
public function getWebsite();
public function getEmail();
// ...
}
class Author implements AuthorInterface {
public function getFullname() {
return $this->fullname;
}
public function getWebsite() {
return $this->website;
}
public function getEmail() {
return $this->email;
}
// More stuff...
}
use AuthorInterface;
class Post {
public function __construct(AuthorInterface $author) {
$this->setAuthor($author);
}
}
There are other methods to make a dependency injection more convenient and robust to use, for example containers...
Symfony framework, since 3.3 release, use PSR-11 containers.
From the official docs:
In Symfony, these useful objects are called services and each service lives inside a very special object called the service container. If you have the service container, then you can fetch a service by using that service's id:
$logger = $container->get('logger');
$entityManager = $container->get('doctrine.orm.entity_manager');
The container allows you to centralize the way objects are constructed. It makes your life easier, promotes a strong architecture and is super fast!
See you soon,
Mathieu