Injektálási módszerek és attribútumok

Konkrét példákon keresztül megnézzük a függőségek átadásának lehetőségeit a prezentereknek, és elmagyarázzuk a inject metódusokat és attribútumokat/annotációkat.

inject*() Módszerek

A prezenterben, mint minden más kódban, a függőségek átadásának előnyös módja a konstruktor használata. Ha azonban a prezenter egy közös őstől (pl. BasePresenter) örököl, akkor jobb, ha a inject*() metódusait használjuk ebben az ősben. Ez a setter speciális esete, ahol a metódus a inject előtaggal kezdődik. Ennek oka, hogy a konstruktort szabadon tartjuk 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;
	}
}

Az alapvető különbség a setterhez képest az, hogy a Nette DI automatikusan meghívja az így elnevezett metódusokat a prezenterekben, amint a példány létrejön, és átadja nekik az összes szükséges függőséget. Egy prezenter több metódust is tartalmazhat inject*() és minden metódusnak tetszőleges számú paramétere lehet.

Ha a függőségeket az ősöknek a konstruktoraikon keresztül adnánk át, akkor az összes leszármazottban meg kellene szereznünk a függőségeket, és át kellene adnunk a parent::__construct(), ami bonyolítja a kódot:

abstract class BasePresenter extends Nette\Application\UI\Presenter
{
	private Foo $foo;

	public function __construct(Foo $foo)
	{
		$this->foo = $foo;
	}
}

class MyPresenter extends BasePresenter
{
	private Bar $bar;

	public function __construct(Foo $foo, Bar $bar)
	{
		parent::__construct($foo); // ez egy komplikáció
		$this->bar = $bar;
	}
}

A inject*() metódusok olyan esetekben is hasznosak, amikor a bemutató vonásokból áll, és mindegyiknek szüksége van a saját függőségére.

Lehetőség van a @inject megjegyzések használatára is, de fontos szem előtt tartani, hogy a kapszulázás megszakad.

Inject Annotációk

Ez a függőség automatikus átadása a bemutató nyilvános tagváltozójának, amely a dokumentációs megjegyzésben a @inject megjegyzéssel van ellátva. A típus a dokumentációs megjegyzésben is megadható, ha 7.4-nél alacsonyabb PHP-t használsz.

class MyPresenter extends Nette\Application\UI\Presenter
{
	/** @inject */
	public Cache $cache;
}

A PHP 8.0 óta egy tulajdonságot a Inject attribútummal is lehet jelölni:

use Nette\DI\Attributes\Inject;

class MyPresenter extends Nette\Application\UI\Presenter
{
	#[Inject]
	public Cache $cache;
}

A Nette DI ismét automatikusan átadja a függőségeket az ilyen módon megjegyzett tulajdonságoknak a prezenterben, amint a példányt létrehozzák.

Ennek a módszernek ugyanazok a hiányosságai vannak, mint a függőségek átadásának egy nyilvános tulajdonsághoz. Azért használjuk a prezenterben, mert nem bonyolítja a kódot, és csak minimális gépelést igényel.