Sobes.tech
Middle

Co je to injekce závislostí a jak se používá při vývoji v PHP?

sobes.tech AI

Odpověď od AI

Injektáž závislostí (DI) je návrhový vzor, ktorý umožňuje jednému objektu získavať závislosti od iného objektu alebo rámca, namiesto ich vlastného vytvárania. To uľahčuje správu závislostí tried a robí kód flexibilnejším, testovateľnejším a udržiavateľnejším.

V PHP sa DI používa na:

  • Zníženie prepojenia (coupling): Triedy nie sú pevne viazané na konkrétne implementácie svojich závislostí.
  • Zjednodušenie jednotkového testovania: Je možné ľahko nahradiť reálne závislosti mock objektmi na testovanie.
  • Zvýšenie flexibility a rozšíriteľnosti: Je možné meniť alebo nahrádzať implementácie závislostí bez zmeny triedy, ktorá ich používa.

Existujú tri hlavné prístupy k injektáži závislostí:

  1. Injektáž cez konštruktor (Constructor Injection): Závislosti sa odovzdávajú ako argumenty konštruktora triedy. Toto je najpreferovanejší spôsob, pretože zabezpečuje prítomnosť potrebných závislostí pri vytváraní objektu.

    <?php
    class DatabaseConnection
    {
        // Detaily pripojenia k databáze
    }
    
    class UserRepository
    {
        private DatabaseConnection $db;
    
        public function __construct(DatabaseConnection $db)
        {
            $this->db = $db;
        }
    
        // Metódy repozitára
    }
    
    // Vytvorenie objektu s injektovaním závislosti
    $db = new DatabaseConnection();
    $userRepository = new UserRepository($db);
    
  2. Injektáž cez setter (Setter Injection): Závislosti sa injektujú cez verejné metódy-settery. Umožňuje robiť závislosti voliteľnými.

    <?php
    class Logger
    {
        // Logovanie
    }
    
    class UserService
    {
        private ?Logger $logger = null; // Voliteľná závislosť
    
        public function setLogger(Logger $logger): void
        {
            $this->logger = $logger;
        }
    
        public function doSomething(): void
        {
            if ($this->logger) {
                $this->logger->log("Robím niečo...");
            }
            // Hlavná logika
        }
    }
    
    // Vytvorenie objektu a voliteľné injektovanie závislosti
    $userService = new UserService();
    $logger = new Logger();
    $userService->setLogger($logger);
    
  3. Injektáž cez rozhranie (Interface Injection): Trieda, ktorej záleží na závislosti, implementuje rozhranie, ktoré definuje metódu na jej nastavenie. Je menej rozšírené v PHP v porovnaní s prvými dvoma.

V reálnych PHP aplikáciách sa často používajú kontajnery injektáže závislostí (Dependency Injection Containers). Ide o knižnice alebo rámce, ktoré automatizujú proces vytvárania objektov a ich závislostí. Kontajner môže analyzovať závislosti triedy a automaticky vytvárať a injektovať potrebné objekty.

Príklady populárnych DI kontajnerov pre PHP:

  • PHP-DI
  • Symfony\DependencyInjection
  • Laravel Service Container (súčasť Laravelu)

Použitie DI kontajnera:

<?php
// Príklad s pseudo-kontajnerom
// Zvyčajne sa kontajner nastavuje pomocou konfigurácie (YAML, PHP polia atď.)

// Konfigurácia kontajnera (zjednodušená)
$container->set(DatabaseConnection::class, function() {
    return new DatabaseConnection(); // Vytvorenie inštancie
});

$container->set(UserRepository::class, function($container) {
    // Injektovanie závislosti DatabaseConnection pri vytváraní UserRepository
    return new UserRepository($container->get(DatabaseConnection::class));
});

// Získanie objektu z kontajnera - kontajner sám vytvorí a injektuje závislosti
$userRepository = $container->get(UserRepository::class);

Na záver, injektovanie závislostí v PHP je kľúčovým vzorom pre tvorbu flexibilného, testovateľného a udržiavateľného kódu, najmä v veľkých projektoch a pri používaní rámcov.