What is a dependency injection container?

I am trying to understand the role of the dependency injection container because it puts me as the main one in the supported code.

As I understand it, DIC is just like the name: a container in which all your dependencies are put together. Instead of looking new Foo\Barthrough the entire application, all new instances are generated inside the container and then transferred to each other where they are needed (for example, Modelan instance is created Database, which is an instance with an instance Config).

I tried to make a very simple DIC. This is the result.

In my front controller, I create a new one App\Core\Container.

My Containerlooks like this:

<?php

namespace App\Core;

use App\Config;

class Container
{
    public $config;
    public $router;
    public $database;

    public $model;
    public $view;
    public $controller;

    public function __construct()
    {
        $this->config   = new Config;
        $this->router   = new Router;
        $this->database = new Database($this->config);
    }

    public function add()
    {
        // add dependencies from the outside?
    }

    public function getInstance(/* string */)
    {
        // return an instance for use somewhere?
    }

    public function newModel($model)
    {
        $model = $this->getModelNamespace() . $model;
        $this->model = new $model($this->database);
        return $this->model;
    }

    private function getModelNamespace()
    {
        $namespace = 'App\Models\\';
        if (array_key_exists('namespace', $this->params = [])) {
            $namespace .= $this->params['namespace'] . '\\';
        }
        return $namespace;
    }

    public function newView($params)
    {
        $this->view = new View($this->model, $params);
        return $this->view;
    }

    public function newController($controller)
    {
        $controller = $this->getControllerNamespace() . $controller;
        $this->controller = new $controller;
        return $this->controller;
    }

    private function getControllerNamespace()
    {
        $namespace = 'App\Controllers\\';
        if (array_key_exists('namespace', $this->params = [])) {
            $namespace .= $this->params['namespace'] . '\\';
        }
        return $namespace;
    }
}

Questions

  • , , ?
  • ?
+4
1

. , - .

?

, . , , . , factory .

. , Container. (.. newModel), , , .

"" factory, , , . , : GenericService . GenericService. , add() getInstance(). -, , !

?

. . , . , , . : SOLID? , .

?

, : , , , . DIC , , .. .

Container, , . , . ( ).

?

. 1 3 : , . PHP-DI , . : autowiring , , - . autowiring, .

?

, . , (, , ..). (: , ).

:

<?php
class Injector
{
    public function make($className)
    {
        $dependencies = [];

        //Create reflection of the class-to-make constructor to get dependencies
        $classReflection = new ReflectionMethod($className, "__construct");

        foreach($classReflection->getParameters() as $parameter) {
            $dependencyName = $parameter->getClass()->getName();

            //Use the injector to make an instance of the dependency
            $dependencies[] = $this->make($dependencyName);
        }

        $class = new ReflectionClass($className);

        //Instantiate the class with all dependencies
        return $class->newInstanceArgs($dependencies);
    }
}

- , ,

class A {
    protected $b;
    public function __construct(B $b) { $this->b = $b; }
    public function output(){ $this->b->foo(); }
}

class B {
    protected $c;
    public function __construct(C $c) { $this->c = $c; }
    public function foo() { $this->c->bar(); }
}

class C {
    public function __construct() { }
    public function bar() { echo "World!"; }
}

$injector = new Injector;

$a = $injector->make("A");
//No need to manually instantiate A dependency, B, or B dependency, C

$a->output();

. , , ( ). , , , .

" ", make(). , , share(). , . , make() , .

Auryn, .

+6

Source: https://habr.com/ru/post/1649805/


All Articles