-
-
Notifications
You must be signed in to change notification settings - Fork 277
Expand file tree
/
Copy pathinject-method-attribute.texy
More file actions
61 lines (42 loc) · 3.44 KB
/
inject-method-attribute.texy
File metadata and controls
61 lines (42 loc) · 3.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
Methoden und Attribute inject
*****************************
.[perex]
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 |dependency-injection:passing-dependencies#Übergabe per 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 |dependency-injection:passing-dependencies#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 |dependency-injection:passing-dependencies#Ü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:
```php
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 |presenter-traits] und jede von ihnen ihre eigene Abhängigkeit benötigt.
`Inject`-Attribute
==================
Dies ist eine Form der [Injection in eine Eigenschaft |dependency-injection:passing-dependencies#Zuweisung zu einer Variablen]. 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)
```php
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 |https://blog.nette.org/de/php-8-0-kompletter-ueberblick-ueber-neuerungen#toc-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.