Co je Dependency Injection?

Dependency Injection (=injektování/vkládání/předání závislostí) je o tom, že každé třídě předáme to, co potřebuje k existenci.

class Sluzba
{
    public function __construct(Sluzba2 $sluzba2, ISluzba3 $sluzba3)
    {
        $this->sluzba2 = $sluzba2;
        $this->sluzba3 = $sluzba3;
    }


    public function dance()
    {
        if (!$this->iCanDance) {
            $this->sluzba2->teachDance($this);
        }

        $this->sluzba3->danceWith($this);
    }
}

Místo toho, aby je skrytě vyhledávala ve svých metodách

class Sluzba
{

    public function dance()
    {
        if (!$this->iCanDance) {
            $sluzba2 = Nette\Environment::getService('Sluzba2');
            $sluzba2->teachDance($this);
        }

        $sluzba3 = Nette\Environment::getService('ISluzba3');
        $sluzba3->danceWith($this);
    }

}
  • docílíme tím větší přehlednosti
  • ztratíme magické schované závislosti, budeme jasně vědět, že když chceme používat Sluzba tak jí musíme předat Sluzba2 a ISluzba3, jinak nebude fungovat
  • lépe se to testuje, můžeme podstrčit jiné instance, které budou kontrolovat co se kam předává (mockování)
  • můžeme použít tu samou třídu na více věcí, jednou jí předáme Sluzba10 implements ISluzba3 a podruhé Sluzba50 implements ISluzba3, bez toho aby jsme museli nějak ovlivňovat „globální prostředí“ a zaneřádili container (serviceLocator)

S tím, že jí závislosti můžeme předat různými způsoby (konstruktor, metoda, vlastnost, ..). A k tomu nám dopomáhej Dependency Injection Container, který se přímo stará o to, že třídám se předá to co potřebují. Na nás je DIC nakonfigurovat tak, aby věděl, co má čemu předat a my pak nemusíme psát ten kód, protože ho za nás automatizovaně vykoná, podle naší konfigurace. Navíc pak můžeme různě služby zase vyměňovat, …

A je to vůbec takové hezčí a voňavější OOP :)