Metodi e attributi di iniezione

In questo articolo, ci concentreremo sui vari modi di passare le dipendenze ai presentatori nel framework Nette. Confronteremo il metodo preferito, ovvero il costruttore, con altre opzioni, quali i metodi e gli attributi di inject.

Anche per i presenter, il passaggio delle dipendenze tramite il costruttore è il metodo preferito. Tuttavia, se si crea un antenato comune da cui ereditano altri presentatori (ad esempio, BasePresenter) e questo antenato ha anch'esso delle dipendenze, si verifica un problema, chiamato constructor hell. Questo problema può essere aggirato utilizzando metodi alternativi, che includono l'iniezione di metodi e attributi (annotazioni).

inject*() Metodi

Si tratta di una forma di passaggio di dipendenze che utilizza i setter. I nomi di questi setter iniziano con il prefisso inject. Nette DI chiama automaticamente questi metodi denominati subito dopo la creazione dell'istanza del presentatore e passa loro tutte le dipendenze richieste. Pertanto, devono essere dichiarati come pubblici.

inject*() I metodi possono essere considerati come una sorta di estensione del costruttore in più metodi. Grazie a ciò, BasePresenter può prendere le dipendenze attraverso un altro metodo e lasciare il costruttore libero per i suoi discendenti:

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;
	}
}

Il presentatore può contenere un numero qualsiasi di metodi inject*() e ognuno può avere un numero qualsiasi di parametri. Questo è ottimo anche per i casi in cui il presentatore è composto da tratti e ognuno di essi richiede la propria dipendenza.

Inject Attributi

Si tratta di una forma di iniezione nelle proprietà. È sufficiente indicare quali proprietà devono essere iniettate e Nette DI passa automaticamente le dipendenze subito dopo aver creato l'istanza del presentatore. Per inserirle, è necessario dichiararle come pubbliche.

Le proprietà sono contrassegnate da un attributo: (in precedenza, si utilizzava l'annotazione /** @inject */)

use Nette\DI\Attributes\Inject; // questa riga è importante

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

Il vantaggio di questo metodo di passaggio delle dipendenze era la sua forma di notazione molto economica. Tuttavia, con l'introduzione della promozione delle proprietà del costruttore, l'uso del costruttore sembra più semplice.

D'altra parte, questo metodo soffre degli stessi difetti del passaggio delle dipendenze nelle proprietà in generale: non abbiamo alcun controllo sulle modifiche della variabile e, allo stesso tempo, la variabile diventa parte dell'interfaccia pubblica della classe, il che è indesiderabile.