Methoden und Attribute inject

In diesem Artikel konzentrieren wir uns auf verschiedene Methoden zur Übergabe von Abhängigkeiten an Presenter im Nette Framework. Wir vergleichen die bevorzugte Methode, nämlich den Konstruktor, mit anderen Möglichkeiten wie inject-Methoden und -Attributen.

Auch für Presenter gilt, dass die Übergabe von Abhängigkeiten über den Konstruktor der bevorzugte Weg ist. Wenn Sie jedoch einen gemeinsamen Vorfahren erstellen, von dem andere Presenter erben (z. B. BasePresenter), und dieser Vorfahre ebenfalls Abhängigkeiten hat, tritt ein Problem auf, das wir Constructor Hell nennen. Dies kann durch alternative Wege umgangen werden, die inject-Methoden und -Attribute (früher Annotationen) darstellen.

inject*()-Methoden

Dies ist eine Form der Abhängigkeitsübergabe per Setter. Der Name dieser Setter beginnt mit dem Präfix inject. Nette DI ruft solche benannten Methoden automatisch sofort nach der Erstellung der Presenter-Instanz auf und übergibt ihnen alle erforderlichen Abhängigkeiten. Sie müssen daher als public deklariert sein.

inject*()-Methoden können als eine Art Erweiterung des Konstruktors auf mehrere Methoden betrachtet werden. Dadurch kann BasePresenter Abhängigkeiten über eine andere Methode übernehmen und den Konstruktor für seine Nachkommen frei lassen:

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

Ein Presenter kann beliebig viele inject*()-Methoden enthalten, und jede kann beliebig viele Parameter haben. Sie eignen sich auch hervorragend in Fällen, in denen der Presenter aus Traits zusammengesetzt ist und jede von ihnen ihre eigene Abhängigkeit benötigt.

Inject-Attribute

Dies ist eine Form der Injection in eine Eigenschaft. Es genügt, zu markieren, in welche Eigenschaften injiziert werden soll, und Nette DI übergibt die Abhängigkeiten automatisch sofort nach der Erstellung der Presenter-Instanz. Damit sie eingefügt werden können, müssen sie als public deklariert sein.

Eigenschaften markieren wir mit einem Attribut: (früher wurde die Annotation /** @inject */ verwendet)

use Nette\DI\Attributes\Inject;  // diese Zeile ist wichtig

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

Der Vorteil dieser Art der Abhängigkeitsübergabe war die sehr sparsame Schreibweise. Mit der Einführung von Constructor Property Promotion erscheint es jedoch einfacher, den Konstruktor zu verwenden.

Im Gegenteil leidet diese Methode unter denselben Nachteilen wie die Übergabe von Abhängigkeiten an Eigenschaften im Allgemeinen: Wir haben keine Kontrolle über Änderungen in der Variablen, und gleichzeitig wird die Variable Teil der öffentlichen Schnittstelle der Klasse, was unerwünscht ist.