Injektálási módszerek és attribútumok
Ebben a cikkben a Nette keretrendszerben a függőségek bemutatóknak való átadásának különböző
módjaira fogunk összpontosítani. Összehasonlítjuk az előnyben részesített módszert, azaz a konstruktort, más
lehetőségekkel, például a inject
módszerekkel és attribútumokkal.
A prezenterek esetében is a függőségek átadása a konstruktor segítségével az előnyben részesített mód. Ha azonban létrehozunk egy közös őst, amelytől más prezenterek is örökölnek (pl. BasePresenter), és ez az ős is rendelkezik függőségekkel, akkor felmerül egy probléma, amelyet konstruktorpokolnak nevezünk. Ez megkerülhető alternatív módszerekkel, amelyek közé tartoznak az injektáló metódusok és attribútumok (annotációk).
inject*()
Módszerek
Ez a függőségi átadás egy formája a setterek használatával. Ezeknek a beállítóknak a neve az inject előtaggal kezdődik. A Nette DI automatikusan meghívja az ilyen nevű metódusokat közvetlenül a prezentáló példány létrehozása után, és átadja az összes szükséges függőséget. Ezért ezeket a metódusokat nyilvánosnak kell deklarálni.
inject*()
A metódusok egyfajta konstruktor-bővítésnek tekinthetők több metódusra. Ennek köszönhetően a
BasePresenter
átveheti a függőségeket egy másik metóduson keresztül, és a konstruktort szabadon hagyhatja a
leszármazottak számára:
abstract class BasePresenter extends Nette\Application\UI\Presenter
{
private Foo $foo;
public function injectBase(Foo $foo): void
{
$this->foo = $foo;
}
}
class MyPresenter extends BasePresenter
{
private Bar $bar;
public function __construct(Bar $bar)
{
$this->bar = $bar;
}
}
A prezenter tetszőleges számú inject*()
metódust tartalmazhat, és mindegyiknek tetszőleges számú
paramétere lehet. Ez olyan esetekben is nagyszerű, amikor a prezenter vonásokból áll, és mindegyiknek saját függőségre van
szüksége.
Inject
Attribútumok
Ez a tulajdonságokba való befecskendezés egy formája. Elegendő megadni, hogy mely tulajdonságokat kell befecskendezni, és a Nette DI automatikusan átadja a függőségeket közvetlenül a prezentáló példány létrehozása után. A beillesztéshez szükséges, hogy publicként deklaráljuk őket.
A tulajdonságokat egy attribútummal jelöljük: (korábban a /** @inject */
megjegyzést használtuk)
use Nette\DI\Attributes\Inject; // ez a sor fontos
class MyPresenter extends Nette\Application\UI\Presenter
{
#[Inject]
public Cache $cache;
}
A függőségek átadásának ezen módszerének előnye a nagyon gazdaságos jelölési forma volt. A konstruktori tulajdonságok promóciójának bevezetésével azonban a konstruktor használata egyszerűbbnek tűnik.
Másrészt ez a módszer ugyanazokkal a hiányosságokkal küzd, mint a függőségek tulajdonságokba történő átadása általában: nincs kontrollunk a változó változásai felett, ugyanakkor a változó az osztály nyilvános interfészének részévé válik, ami nem kívánatos.