Dependency Injection (DI)

I can’t live without you, then, you are my dependence. To put it bluntly:

Not mine, but what I need, what I depend on. Everything that needs to be externally provided requires dependency injection.

Dependency Injection Examples

interface Girl {
            // Boy need knows that I have some abilities.
        }

class LoliGril implement Girl {
        // I will implement Girl's abilities.
    }
 
class Vixen implement Girl {
        // Vixen definitely is a girl, do not doubt it.
    }
 
class Boy {
    protected $girl;

    public function __construct(Girl $girl) {
        $this->girl = $girl; }}$loliGirl = new LoliGirl();
$vixen = new Vixen();
 
$boy = new Boy($loliGirl);
$boy = new Boy($vixen);
$boy = new Boy();  // Error; Boy must have girlfriend!
Copy the code

Dependency injection

Constructor injection

class Book
{
    private $db_conn;

    public function __construct($db_conn)
    {
        $this->db_conn = $db_conn; }}Copy the code

2. Setter injection

        class Book
        {
            private $db;
            private $file;

            function setdb($db)
            {
                $this->db = $db;
            }

            function setfile($file)
            {
                $this->file = $file; }}class file
        {}class db
        {}// ...

        class test
        {
            $book = new Book();
            $book->setdb(new db());
            $book->setfile(new file());
        }
Copy the code

Summary:

Because most applications have two or more classes working with each other to implement business logic, each object needs to get a reference to the object it works with (that is, the object it depends on). If this fetching process is implemented on its own, it results in highly coupled code that is difficult to maintain and debug. Hence the concept of dependency injection, which solves the following problems:

  • Decoupling between dependencies
  • Unit testing, easy to Mock

The code is clear, but when we inject many dependencies, it means adding many lines, which can be difficult to manage.

A better solution is to create a class as a container for all dependencies, where you can store, create, retrieve, and find the dependencies you need. Let’s start with the concept of IOC

Dependency Lookup (DL)

Dependency lookup is an implementation of the inversion of control design principle. The general idea is that a controlled object in a container uses the container’s API to find the resources it depends on and the objects it collaborates with. This approach reduces dependencies between objects, but it also uses the container’s API, making it impossible to use and test objects outside the container. Dependency lookup is a more traditional IOC implementation.

There are two ways to find:

  • Dependency drag (DP) : How an injected object interacts with a component through dependency drag.
  • Context-dependent lookup (CDL) : similar to dependency drag in some respects, but in context-dependent lookup, the lookup takes place in container-managed resources, rather than from a centralized registry, and usually at some set point.

Dependency injection/lookup comparison

type Depend on the processing Achieve convenience Code intrusion API dependency readability
Rely on to find Actively seek Relatively complicated Intrusion into business logic Dependency container API good
Dependency injection Passive provide Relatively convenient Less invasive Does not rely on the container API general

Inversion Of Control (IOC)

Inversion of control (INVERSION of control) is a design principle in object-oriented programming that can reduce coupling between computer codes. One of the most common is called Dependency Injection (DI) and another is called Dependency Lookup. With inversion of control, when an object is created, it is passed a reference to the object on which it depends by an external entity that regulates all objects in the system. In other words, dependencies are injected into objects.

class Ioc
{
    protected $db_conn;

    public static function make_book()
    {
        $new_book = new Book();
        $new_book->set_db(self: :$db_conn);
        / /...
        / /...
        // Other dependency injection
        return $new_book; }}Copy the code

$newone = Ioc:: Makebook (); $newone = Ioc:: Makebook ();

The above is a concrete example of container. It is better to use Registry instead of a specific dependency injection method

/** * Inversion of control class */
class Ioc
{
    / * * *@varArray Registers the dependent array */
    protected static $registry = array(a);/** * Add a resolve (anonymous function) to the Registry array **@paramString $name Dependency identifier *@paramClosure $resolve An anonymous function used to create an instance *@return void
     */
    public static function register($name.Closure $resolve)
    {
        static: :$registry[$name] = $resolve;
    }

    /** * returns an instance **@paramString $name Dependent identifier *@return mixed
     * @throws \Exception
     */
    public static function resolve($name)
    {
        if (static::registered($name)) {
            $name = static: :$registry[$name];
            return $name(a); }throw new \Exception("Nothing registered with that name");
    }

    /** * Query whether a dependent instance exists **@param string $name
     * @return bool
     */
    public static function registered($name)
    {
        return array_key_exists($name.static: :$registry); }}Copy the code

You can now register and inject one as follows

Ioc::register("book".function () {
            $book = new Book();
            $book->setdb('db');
            $book->setfile('file');

            return $book;
    });

// Inject dependencies
        $book = Ioc::resolve('book');
Copy the code

The problem summary

1. Who are the participants?

A: There are usually three actors, one is an object; One is an IoC/DI container; The other is an external resource for an object. Again, an object is an arbitrary, ordinary Java object; The IoC/DI container simply refers to a framework used to implement IoC/DI functions; The external resources of an object refer to the resources needed by the object, but obtained from the outside of the object, all referred to as resources, such as other objects needed by the object, or file resources needed by the object, and so on.

2. Dependence: Who depends on whom? Why is there dependency?

A: An object depends on an IoC/DI container. Dependencies are inevitable. In a project, there are a variety of relationships between classes that cannot all be completely independent, which forms dependencies. Traditional development calls directly when using other classes, which creates strong coupling, is something to avoid. Dependency injection borrows containers to decouple dependent objects.

3. Inject: Who inject into whom? What exactly is injected?

A: Inject the required external resources into the object through the container

4. Inversion of control: Who controls whom? Control what? Why is it called reversal?

A: The IoC/DI container controls objects, mainly the creation of object instances. Inversion is relative to forward, so what is forward? If you were to use C in A regular application, what would you do? It is, of course, directly creating C objects, that is, actively obtaining the required external resource C in class A, which is called positive. So what is the reverse? Instead of actively acquiring C, class A passively waits for the IoC/DI container to acquire an instance of C and then reversely inject it into class A.

Are DEPENDENCY injection and inversion of control the same concept?

A: Dependency injection (DI) is described from the perspective of the application. It can be described in a complete point: the application relies on the container to create and inject the external resources it needs; Inversion of control is described from the perspective of the container, describing the completeness point: the container controls the application, and the container inversely injects the external resources needed by the application.

The original:

  • PHP Dependency Injection (DI) and Inversion of Control (IoC) – 52PHP – Cnblogs.com
  • Dependency Search and Dependency Injection – Xinsen Wang – Blogpark (CNblogs.com)

Reference:

  • Dependency injection and Inversion of control in Laravel