Méthodes et attributs inject

Dans cet article, nous nous concentrerons sur les différentes manières de transmettre des dépendances aux presenters dans le framework Nette. Nous comparerons la méthode préférée, qui est le constructeur, avec d'autres options telles que les méthodes et les attributs inject.

Pour les presenters également, la transmission de dépendances via le constructeur est la voie préférée. Cependant, si vous créez un ancêtre commun dont héritent d'autres presenters (par exemple BasePresenter), et que cet ancêtre a également des dépendances, un problème survient que nous appelons l'enfer du constructeur. Celui-ci peut être contourné en utilisant des voies alternatives, qui sont les méthodes et les attributs (annotations) inject.

Méthodes inject*()

Il s'agit d'une forme de transmission de dépendances par setter. Le nom de ces setters commence par le préfixe inject. Nette DI appelle automatiquement les méthodes ainsi nommées juste après la création de l'instance du presenter et leur transmet toutes les dépendances requises. Elles doivent donc être déclarées comme public.

Les méthodes inject*() peuvent être considérées comme une sorte d'extension du constructeur en plusieurs méthodes. Grâce à cela, BasePresenter peut recevoir des dépendances via une autre méthode et laisser le constructeur libre pour ses descendants :

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

Un presenter peut contenir un nombre quelconque de méthodes inject*() et chacune peut avoir un nombre quelconque de paramètres. Elles sont également très utiles dans les cas où le presenter est composé de traits et que chacun d'eux nécessite sa propre dépendance.

Attributs Inject

Il s'agit d'une forme d'injection dans la propriété. Il suffit de marquer les propriétés dans lesquelles injecter, et Nette DI transmet automatiquement les dépendances juste après la création de l'instance du presenter. Pour pouvoir les insérer, il est nécessaire de les déclarer comme public.

Nous marquons les propriétés avec un attribut : (auparavant, l'annotation /** @inject */ était utilisée)

use Nette\DI\Attributes\Inject;  // cette ligne est importante

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

L'avantage de cette méthode de transmission des dépendances était sa forme d'écriture très concise. Cependant, avec l'arrivée de la promotion des propriétés du constructeur, il semble plus facile d'utiliser le constructeur.

Inversement, cette méthode souffre des mêmes défauts que la transmission de dépendances aux propriétés en général : nous n'avons aucun contrôle sur les changements dans la variable, et en même temps, la variable devient partie intégrante de l'interface publique de la classe, ce qui n'est pas souhaitable.