-
-
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.29 KB
/
inject-method-attribute.texy
File metadata and controls
61 lines (42 loc) · 3.29 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
Metodi e attributi inject
*************************
.[perex]
In questo articolo ci concentreremo sui diversi modi di passare le dipendenze ai presenter nel framework Nette. Confronteremo il metodo preferito, che è il costruttore, con altre opzioni come i metodi e gli attributi `inject`.
Anche per i presenter vale che il passaggio delle dipendenze tramite il [costruttore |dependency-injection:passing-dependencies#Passaggio tramite costruttore] è il percorso preferito. Tuttavia, se si crea un antenato comune da cui ereditano altri presenter (ad es. `BasePresenter`), e questo antenato ha anch'esso delle dipendenze, si verifica un problema che chiamiamo [constructor hell |dependency-injection:passing-dependencies#Constructor hell]. Questo può essere aggirato utilizzando percorsi alternativi, che sono rappresentati dai metodi e dagli attributi (annotazioni) `inject`.
Metodi `inject*()`
==================
È una forma di passaggio della dipendenza tramite [setter |dependency-injection:passing-dependencies#Passaggio tramite setter]. Il nome di questi setter inizia con il prefisso `inject`. Nette DI chiama automaticamente i metodi così denominati subito dopo la creazione dell'istanza del presenter e passa loro tutte le dipendenze richieste. Devono quindi essere dichiarati come public.
I metodi `inject*()` possono essere considerati come una sorta di estensione del costruttore in più metodi. Grazie a ciò, `BasePresenter` può ricevere le dipendenze tramite un altro metodo e lasciare il costruttore libero per i suoi discendenti:
```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;
}
}
```
Un presenter può contenere un numero qualsiasi di metodi `inject*()` e ognuno può avere un numero qualsiasi di parametri. Sono ottimi anche nei casi in cui il presenter è [composto da trait |presenter-traits] e ognuno di essi richiede la propria dipendenza.
Attributi `Inject`
==================
È una forma di [iniezione nella proprietà |dependency-injection:passing-dependencies#Impostazione di una variabile]. È sufficiente contrassegnare in quali variabili iniettare e Nette DI passerà automaticamente le dipendenze subito dopo la creazione dell'istanza del presenter. Per poterle inserire, è necessario dichiararle come public.
Contrassegniamo le proprietà con un attributo: (in precedenza si usava l'annotazione `/** @inject */`)
```php
use Nette\DI\Attributes\Inject; // questa riga è importante
class MyPresenter extends Nette\Application\UI\Presenter
{
#[Inject]
public Cache $cache;
}
```
Il vantaggio di questo modo di passare le dipendenze era la forma di scrittura molto concisa. Tuttavia, con l'avvento della [constructor property promotion |https://blog.nette.org/it/php-8-0-complete-overview-of-news#toc-constructor-property-promotion], sembra più facile utilizzare il costruttore.
Al contrario, questo metodo soffre degli stessi svantaggi del passaggio delle dipendenze alle proprietà in generale: non abbiamo controllo sulle modifiche nella variabile e allo stesso tempo la variabile diventa parte dell'interfaccia pubblica della classe, il che è indesiderabile.