Dependency Injection Инъекция, внедрение зависимостей -- что это такое
Primary tabs
Forums:
Dependency Injection - это концепция построения приложения, при которой за каждую функцию приложения отвечает один, условно независимый объект (сервис), который может иметь необходимость использовать другие объекты (зависимости), известные ему интерфейсами. Концепция реализуется в различных языках программирования: PHP, Java, JavaScript, С#, Python и др.
Такой подход, когда функциональные блоки выделяются в сервисы, принято называть сервисно-ориентированной архитектурой (Service-oriented architecture, SOA).
Термин переводится как "внедрение зависимостей".
Как это работает
Если некий сервис использует какие-то данные, он получает их в готовом виде. И он "не знает, и не зависит, и не истересуется" логикой их получения. За это отвечает отдельный механизм.
На картинке такой механизм назван "инъектором":
Для чего это нужно
Инкапсуляция, разделение отвественности за определённый функционал между разными сервисами.
Пример
<?php
/**
* Класс конфигурация базы данных
*/
class DbConfiguration{
private $host;
private $port;
private $username;
private $password;
public function __construct(string $host, int $port, string $username, string $password){
// вся соль Di находится в строчках ниже
$this->host = $host;
$this->port = $port;
$this->username = $username;
$this->password = $password;
}
public function getHost(){
return $this->host;
}
public function getPort(){
return $this->port;
}
public function getUsername(){
return $this->username;
}
public function getPassword(){
return $this->password;
}
}
/**
* Класс соединение с базой данных
*/
class DbConnection{
private $configuration;
public function __construct(DbConfiguration $config){
// вся соль Di находится в строчке ниже
$this->configuration = $config;
}
public function getDsn(){
// примечание: это не реальный dsn, разделители в реальном dsn другие
return sprintf(
'%s:%s@%s:%d',
$this->configuration->getUsername(),
$this->configuration->getPassword(),
$this->configuration->getHost(),
$this->configuration->getPort()
);
}
}
// создаем объект конфигурации базы данных, передав в конструктор параметры
$config = new DbConfiguration('localhost', 3306, 'username', 'password');
// создаем объект соединения с базой, передав в конструктор объект конфигурации
// использование Di дает слабосвязность кода
$connection = new DbConnection($config);В Symfony (PHP) эта концепция реализуется с помощью Контейнера (Conteiner Component). Примеры реализации и правила конфигурации сервисов в Symfony можно посмотреть здесь.
Сравнение Инъекции зависимости с Локатором служб ("противоложный" централизованный подход)
Сервис локатор работает так:

-- собирая для нас данные по запросу, при этом мы явно обращаемся к локатору.
А вот инъекция зависимостей поставляет эти данные "на вход" модулей/объектов и они не знают, что инъектор вообще существует, а потому и не зависят от него:
Видео материалы
Источники
- Log in to post comments
- 7868 reads
vedro-compota
Tue, 02/13/2018 - 18:54
Permalink
из статьи не ясен уровень
из статьи не ясен уровень абстракции. Ведь можно очень по-разному разбивать приложение на функции. Чем это отличатся от "чистого" ООП?
_____________
матфак вгу и остальная классика =)
melisa
Tue, 02/13/2018 - 19:02
Permalink
как я поняла
Как я поняла, от ООП инъекции отличаются тем, что
vedro-compota
Tue, 02/13/2018 - 19:07
Permalink
Каждый класс (сервис)
это как-то очень невнятно. Во первых "абсолютно" не бывает -- у вас в заметке уже написано, что интерфейс фиксированный:
А значит эксплуатирующий класс чего-то уже ожидает от используемого. Но это всегда происходит когда применяются интерфейсы.
_____________
матфак вгу и остальная классика =)
melisa
Wed, 02/14/2018 - 17:46
Permalink
Во первых "абсолютно" не
здесь слово "абсолютно" относится к функционалу, а не сервису.
vedro-compota
Mon, 11/24/2025 - 18:14
Permalink
<?php
<?php class A { consctuctor(string $username) { } a() } ServiceLocator () { static getA() { return A; } static setA(A $a) { $this->a = $a; return A; } } // bootstarp.php $username = $_GET(); // $a = new A($username); ServiceLocator::setA($a); // инициализация: DiInjector::setA(); // class B class B { constcructor(A $a) { $this->a = $a; } b(A $a) { $this->a(); } } // где-то еще $a = new A('test'); $b = new B($a);_____________
матфак вгу и остальная классика =)