Nette Documentation Preview

syntax
Definizione dei servizi
***********************

.[perex]
La configurazione è il luogo in cui diciamo al container DI come creare i singoli servizi e come collegarli alle loro dipendenze. Nette offre un modo molto chiaro ed elegante di farlo.

La sezione `services` del file di configurazione NEON è il luogo in cui definiamo i nostri servizi e le loro configurazioni. Guardiamo un semplice esempio che definisce un servizio chiamato `database`, il quale rappresenta un'istanza della classe `PDO`:

```neon
services:
	database: PDO('sqlite::memory:')
```

La configurazione qui sopra produce il seguente metodo factory nel [container DI|container]:

```php
public function createServiceDatabase(): PDO
{
	return new PDO('sqlite::memory:');
}
```

I nomi dei servizi permettono di farvi riferimento in altre parti del file di configurazione, con il formato `@nomeServizio`. Se non serve assegnare un nome al servizio, possiamo semplicemente usare un trattino (`-`):

```neon
services:
	- PDO('sqlite::memory:')
```

Per ottenere un servizio dal container DI possiamo usare il metodo `getService()`, con il nome del servizio come parametro, oppure il metodo `getByType()`, con il tipo del servizio:

```php
$database = $container->getService('database');
$database = $container->getByType(PDO::class);
```


Creazione dei servizi
=====================

Di norma creiamo un servizio semplicemente istanziando una determinata classe. Per esempio:

```neon
services:
	database: PDO('mysql:host=127.0.0.1;dbname=test', root, secret)
```

Se dobbiamo ampliare la configurazione con altre chiavi, la definizione si può spezzare su più righe:

```neon
services:
	database:
		create: PDO('sqlite::memory:')
		setup: ...
```

La chiave `create` ha un alias, `factory`; entrambe le varianti sono di uso comune. Consigliamo però di usare `create`.

Gli argomenti del costruttore o del metodo factory si possono indicare, in alternativa, con la chiave `arguments`:

```neon
services:
	database:
		create: PDO
		arguments: ['mysql:host=127.0.0.1;dbname=test', root, secret]
```

I servizi non devono per forza essere creati con la semplice istanziazione di una classe: possono essere anche il risultato della chiamata di metodi statici o di metodi di altri servizi:

```neon
services:
	database: DatabaseFactory::create()
	router: @routerFactory::create()
```

Notate che, per semplicità, si usa `::` invece di `->`, vedi [#Linguaggio delle espressioni]. Verranno generati questi metodi factory:

```php
public function createServiceDatabase(): PDO
{
	return DatabaseFactory::create();
}

public function createServiceRouter(): RouteList
{
	return $this->getService('routerFactory')->create();
}
```

Il container DI deve conoscere il tipo del servizio che sta creando. Se creiamo un servizio con un metodo privo di tipo di ritorno dichiarato, dobbiamo indicare esplicitamente questo tipo nella configurazione:

```neon
services:
	database:
		create: DatabaseFactory::create()
		type: PDO
```


Argomenti
=========

Passiamo gli argomenti ai costruttori e ai metodi in modo molto simile a come si fa in PHP:

```neon
services:
	database: PDO('mysql:host=127.0.0.1;dbname=test', root, secret)
```

Per una migliore leggibilità possiamo elencare gli argomenti su righe separate. In tal caso le virgole diventano facoltative:

```neon
services:
	database: PDO(
		'mysql:host=127.0.0.1;dbname=test'
		root
		secret
	)
```

Potete anche dare un nome agli argomenti, eliminando la necessità di preoccuparvi del loro ordine:

```neon
services:
	database: PDO(
		username: root
		password: secret
		dsn: 'mysql:host=127.0.0.1;dbname=test'
	)
```

Se volete omettere certi argomenti e usarne i valori predefiniti, oppure farvi iniettare un servizio tramite l'[autowiring|autowiring], usate un trattino basso (`_`):

```neon
services:
	foo: Foo(_, %appDir%)
```

Gli argomenti possono comprendere servizi, parametri e molto altro, vedi [#Linguaggio delle espressioni].


Setup
=====

Nella sezione `setup` definiamo i metodi da chiamare al momento della creazione del servizio.

```neon
services:
	database:
		create: PDO(%dsn%, %user%, %password%)
		setup:
			- setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)
```

In PHP avrebbe questo aspetto:

```php
public function createServiceDatabase(): PDO
{
	$service = new PDO('...', '...', '...');
	$service->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
	return $service;
}
```

Oltre alle chiamate di metodo si possono anche assegnare valori alle proprietà. È supportata anche l'aggiunta di elementi agli array, il che richiede di racchiudere tra apici l'accesso all'array, per evitare conflitti con la sintassi NEON:

```neon
services:
	foo:
		create: Foo
		setup:
			- $value = 123
			- '$onClick[]' = [@bar, clickHandler]
```

Che in codice PHP avrebbe questo aspetto:

```php
public function createServiceFoo(): Foo
{
	$service = new Foo;
	$service->value = 123;
	$service->onClick[] = [$this->getService('bar'), 'clickHandler'];
	return $service;
}
```

Nel setup potete però chiamare anche metodi statici o metodi di altri servizi. Se dovete passare come argomento il servizio corrente stesso, fatevi riferimento con `@self`:

```neon
services:
	foo:
		create: Foo
		setup:
			- My\Helpers::initializeFoo(@self)
			- @anotherService::setFoo(@self)
```

Notate che, per semplicità, si usa `::` invece di `->`, vedi [#Linguaggio delle espressioni]. Verrà generato questo metodo factory:

```php
public function createServiceFoo(): Foo
{
	$service = new Foo;
	My\Helpers::initializeFoo($service);
	$this->getService('anotherService')->setFoo($service);
	return $service;
}
```


Linguaggio delle espressioni
============================

Nette DI offre un linguaggio delle espressioni eccezionalmente ricco, con il quale possiamo definire quasi qualsiasi cosa. Nei file di configurazione possiamo quindi usare i [parametri |configuration#Parametri]:

```neon
# parametro
%wwwDir%

# valore di un parametro sotto una chiave
%mailer.user%

# parametro dentro una stringa
'%wwwDir%/images'
```

Inoltre creare oggetti, chiamare metodi e funzioni:

```neon
# crea un oggetto
DateTime()

# chiama un metodo statico
Collator::create(%locale%)

# chiama una funzione PHP
::getenv(DB_USER)
```

Fare riferimento ai servizi per nome oppure per tipo:

```neon
# servizio per nome
@database

# servizio per tipo
@Nette\Database\Connection
```

Usare la first-class callable syntax: .{data-version:3.2.0}

```neon
# crea una callback, equivalente a [@user, logout]
@user::logout(...)
```

Usare le costanti:

```neon
# costante di classe
FilesystemIterator::SKIP_DOTS

# ottiene una costante globale con la funzione PHP constant()
::constant(\PHP_VERSION)
```

Accedere alle proprietà pubbliche e alle costanti di un servizio con `@servizio::membro`. Se il nome indichi una proprietà o una costante lo decide la sua prima lettera: un'iniziale minuscola significa una proprietà pubblica, una maiuscola significa una costante:

```neon
# proprietà pubblica di un servizio (inizia con una lettera minuscola)
@settings::apiUrl

# costante di classe di un servizio (inizia con una lettera maiuscola)
@settings::Version
```

Le chiamate di metodo si possono concatenare come in PHP. Per semplicità si usa `::` invece di `->`:

```neon
DateTime()::format('Y-m-d')
# PHP: (new DateTime())->format('Y-m-d')

@http.request::getUrl()::getHost()
# PHP: $this->getService('http.request')->getUrl()->getHost()
```

Potete usare queste espressioni ovunque: nella [creazione dei servizi |#Creazione dei servizi], negli [argomenti |#Argomenti], nella sezione [setup |#Setup] oppure nei [parametri |configuration#Parametri]:

```neon
parameters:
	ipAddress: @http.request::getRemoteAddress()

services:
	database:
		create: DatabaseFactory::create( @anotherService::getDsn() )
		setup:
			- initialize( ::getenv('DB_USER') )
```


Funzioni speciali
-----------------

Nei file di configurazione potete usare queste funzioni speciali:

- `not()` nega un valore
- `bool()`, `int()`, `float()`, `string()` conversione senza perdita nel tipo indicato .{data-version:3.0.5}
- `typed()` crea un array di tutti i servizi del tipo indicato
- `tagged()` crea un array di tutti i servizi con il tag indicato

```neon
services:
	- Foo(
		id: int(::getenv('ProjectId'))
		productionMode: not(%debugMode%)
	)
```

A differenza della conversione standard di PHP, come `(int)`, la conversione senza perdita solleva un'eccezione per i valori non numerici.

La funzione `typed()` crea un array di tutti i servizi del tipo indicato (classe o interfaccia). Esclude i servizi che hanno l'autowiring disattivato. Si possono indicare anche più tipi, separati da virgole.

```neon
services:
	- BarsDependent( typed(Bar) )
```

Un array di servizi di un certo tipo si può passare come argomento anche automaticamente, tramite l'[autowiring |autowiring#Collezione di servizi].

La funzione `tagged()` crea invece un array di tutti i servizi con un determinato tag. Anche qui potete indicare più tag separati da virgole.

```neon
services:
	- LoggersDependent( tagged(logger) )
```


Autowiring
==========

La chiave `autowired` vi permette di influire sul comportamento dell'autowiring per un determinato servizio. Per i dettagli vedi il [capitolo sull'autowiring|autowiring].

```neon
services:
	foo:
		create: Foo
		autowired: false     # il servizio foo è escluso dall'autowiring
```


Servizi pigri .{data-version:3.2.4}
===================================

Il caricamento pigro è una tecnica che rimanda la creazione di un servizio finché non serve davvero. Nella configurazione globale potete [attivare la creazione pigra |configuration#Servizi pigri] per tutti i servizi in una volta. Per i singoli servizi potete poi sovrascrivere questo comportamento:

```neon
services:
	foo:
		create: Foo
		lazy: false
```

Quando un servizio è definito come pigro, chiedendolo al container DI riceviamo un oggetto proxy speciale. Questo proxy sembra e si comporta esattamente come il servizio reale, ma l'inizializzazione vera e propria (la chiamata del costruttore e quelle del setup) avviene solo al primo accesso a uno qualsiasi dei suoi metodi o delle sue proprietà.

Tenete presente che, poiché il servizio viene creato più tardi, anche gli errori nella sua configurazione si manifestano più tardi. Per esempio, credenziali del database sbagliate non si riveleranno all'avvio dell'applicazione, ma solo alla prima query.

La creazione pigra attenua anche le dipendenze circolari, cioè la situazione in cui il servizio A richiede il servizio B e contemporaneamente B richiede A. Senza di essa il container segnala l'errore `Circular reference detected`. Con un proxy pigro il servizio A riceve solo un proxy del servizio B, che si inizializza quando viene davvero usato, in un momento in cui A esiste già. Una dipendenza circolare, comunque, segnala una progettazione difettosa, ed è meglio liberarsene.

.[note]
Il caricamento pigro richiede PHP 8.4 o successivo e funziona solo per i servizi creati istanziando direttamente una classe (per esempio `create: Foo`), non per quelli creati da un metodo factory. Non si può usare nemmeno per le classi che in ultima analisi estendono una classe interna di PHP. Quando il caricamento pigro non si può applicare, il flag `lazy: true` viene ignorato in silenzio.


Tag
===

I tag servono ad aggiungere informazioni supplementari ai servizi. Potete assegnare a un servizio uno o più tag:

```neon
services:
	foo:
		create: Foo
		tags:
			- cached
```

I tag possono anche contenere valori:

```neon
services:
	foo:
		create: Foo
		tags:
			logger: monolog.logger.event
```

Per ottenere tutti i servizi associati a determinati tag potete usare la funzione `tagged()`:

```neon
services:
	- LoggersDependent( tagged(logger) )
```

All'interno del container DI potete ottenere i nomi di tutti i servizi con un determinato tag usando il metodo `findByTag()`:

```php
$names = $container->findByTag('logger');
// $names è un array con i nomi dei servizi come chiavi e i valori dei tag come valori
// per esempio ['foo' => 'monolog.logger.event', ...]
```


Modalità inject
===============

Usando il flag `inject: true` si attiva la dependency injection tramite le proprietà pubbliche con l'attributo [Inject |best-practices:inject-method-attribute#Attributi Inject] e tramite i metodi [inject*() |best-practices:inject-method-attribute#Metodi inject*()].

```neon
services:
	articles:
		create: App\Model\Articles
		inject: true
```

Per impostazione predefinita la modalità `inject` è attiva solo per i presenter.


Modifiche ai servizi
====================

Il container DI contiene numerosi servizi aggiunti da estensioni integrate o [dell'utente|extensions]. Potete modificare le definizioni di questi servizi esistenti direttamente nella configurazione. Per esempio potete cambiare la classe del servizio `application.application`, che di norma è `Nette\Application\Application`, con un'altra:

```neon
services:
	application.application:
		create: MyApplication
		alteration: true
```

Il flag `alteration` indica che stiamo solo modificando un servizio esistente. Funge anche da protezione: se il servizio da modificare non esiste, la compilazione fallisce con un'eccezione.

Possiamo anche integrare il setup:

```neon
services:
	application.application:
		create: MyApplication
		alteration: true
		setup:
			- '$onStartup[]' = [@resource, init]
```

Non dovete identificare un servizio con il suo nome interno: potete fare riferimento a esso per tipo. L'esempio precedente si può scrivere anche così:

```neon
services:
	@Nette\Application\Application:
		create: MyApplication
```

Modificando un servizio potremmo voler rimuovere gli argomenti, gli elementi del setup o i tag originali, con la chiave `reset`:

```neon
services:
	application.application:
		create: MyApplication
		alteration: true
		reset:
			arguments: true
			setup: true
			tags: true
```

Se volete rimuovere un servizio aggiunto da un'estensione, potete farlo così:

```neon
services:
	cache.journal: false
```

Definizione dei servizi

La configurazione è il luogo in cui diciamo al container DI come creare i singoli servizi e come collegarli alle loro dipendenze. Nette offre un modo molto chiaro ed elegante di farlo.

La sezione services del file di configurazione NEON è il luogo in cui definiamo i nostri servizi e le loro configurazioni. Guardiamo un semplice esempio che definisce un servizio chiamato database, il quale rappresenta un'istanza della classe PDO:

services:
	database: PDO('sqlite::memory:')

La configurazione qui sopra produce il seguente metodo factory nel container DI:

public function createServiceDatabase(): PDO
{
	return new PDO('sqlite::memory:');
}

I nomi dei servizi permettono di farvi riferimento in altre parti del file di configurazione, con il formato @nomeServizio. Se non serve assegnare un nome al servizio, possiamo semplicemente usare un trattino (-):

services:
	- PDO('sqlite::memory:')

Per ottenere un servizio dal container DI possiamo usare il metodo getService(), con il nome del servizio come parametro, oppure il metodo getByType(), con il tipo del servizio:

$database = $container->getService('database');
$database = $container->getByType(PDO::class);

Creazione dei servizi

Di norma creiamo un servizio semplicemente istanziando una determinata classe. Per esempio:

services:
	database: PDO('mysql:host=127.0.0.1;dbname=test', root, secret)

Se dobbiamo ampliare la configurazione con altre chiavi, la definizione si può spezzare su più righe:

services:
	database:
		create: PDO('sqlite::memory:')
		setup: ...

La chiave create ha un alias, factory; entrambe le varianti sono di uso comune. Consigliamo però di usare create.

Gli argomenti del costruttore o del metodo factory si possono indicare, in alternativa, con la chiave arguments:

services:
	database:
		create: PDO
		arguments: ['mysql:host=127.0.0.1;dbname=test', root, secret]

I servizi non devono per forza essere creati con la semplice istanziazione di una classe: possono essere anche il risultato della chiamata di metodi statici o di metodi di altri servizi:

services:
	database: DatabaseFactory::create()
	router: @routerFactory::create()

Notate che, per semplicità, si usa :: invece di ->, vedi Linguaggio delle espressioni. Verranno generati questi metodi factory:

public function createServiceDatabase(): PDO
{
	return DatabaseFactory::create();
}

public function createServiceRouter(): RouteList
{
	return $this->getService('routerFactory')->create();
}

Il container DI deve conoscere il tipo del servizio che sta creando. Se creiamo un servizio con un metodo privo di tipo di ritorno dichiarato, dobbiamo indicare esplicitamente questo tipo nella configurazione:

services:
	database:
		create: DatabaseFactory::create()
		type: PDO

Argomenti

Passiamo gli argomenti ai costruttori e ai metodi in modo molto simile a come si fa in PHP:

services:
	database: PDO('mysql:host=127.0.0.1;dbname=test', root, secret)

Per una migliore leggibilità possiamo elencare gli argomenti su righe separate. In tal caso le virgole diventano facoltative:

services:
	database: PDO(
		'mysql:host=127.0.0.1;dbname=test'
		root
		secret
	)

Potete anche dare un nome agli argomenti, eliminando la necessità di preoccuparvi del loro ordine:

services:
	database: PDO(
		username: root
		password: secret
		dsn: 'mysql:host=127.0.0.1;dbname=test'
	)

Se volete omettere certi argomenti e usarne i valori predefiniti, oppure farvi iniettare un servizio tramite l'autowiring, usate un trattino basso (_):

services:
	foo: Foo(_, %appDir%)

Gli argomenti possono comprendere servizi, parametri e molto altro, vedi Linguaggio delle espressioni.

Setup

Nella sezione setup definiamo i metodi da chiamare al momento della creazione del servizio.

services:
	database:
		create: PDO(%dsn%, %user%, %password%)
		setup:
			- setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)

In PHP avrebbe questo aspetto:

public function createServiceDatabase(): PDO
{
	$service = new PDO('...', '...', '...');
	$service->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
	return $service;
}

Oltre alle chiamate di metodo si possono anche assegnare valori alle proprietà. È supportata anche l'aggiunta di elementi agli array, il che richiede di racchiudere tra apici l'accesso all'array, per evitare conflitti con la sintassi NEON:

services:
	foo:
		create: Foo
		setup:
			- $value = 123
			- '$onClick[]' = [@bar, clickHandler]

Che in codice PHP avrebbe questo aspetto:

public function createServiceFoo(): Foo
{
	$service = new Foo;
	$service->value = 123;
	$service->onClick[] = [$this->getService('bar'), 'clickHandler'];
	return $service;
}

Nel setup potete però chiamare anche metodi statici o metodi di altri servizi. Se dovete passare come argomento il servizio corrente stesso, fatevi riferimento con @self:

services:
	foo:
		create: Foo
		setup:
			- My\Helpers::initializeFoo(@self)
			- @anotherService::setFoo(@self)

Notate che, per semplicità, si usa :: invece di ->, vedi Linguaggio delle espressioni. Verrà generato questo metodo factory:

public function createServiceFoo(): Foo
{
	$service = new Foo;
	My\Helpers::initializeFoo($service);
	$this->getService('anotherService')->setFoo($service);
	return $service;
}

Linguaggio delle espressioni

Nette DI offre un linguaggio delle espressioni eccezionalmente ricco, con il quale possiamo definire quasi qualsiasi cosa. Nei file di configurazione possiamo quindi usare i parametri:

# parametro
%wwwDir%

# valore di un parametro sotto una chiave
%mailer.user%

# parametro dentro una stringa
'%wwwDir%/images'

Inoltre creare oggetti, chiamare metodi e funzioni:

# crea un oggetto
DateTime()

# chiama un metodo statico
Collator::create(%locale%)

# chiama una funzione PHP
::getenv(DB_USER)

Fare riferimento ai servizi per nome oppure per tipo:

# servizio per nome
@database

# servizio per tipo
@Nette\Database\Connection

Usare la first-class callable syntax:

# crea una callback, equivalente a [@user, logout]
@user::logout(...)

Usare le costanti:

# costante di classe
FilesystemIterator::SKIP_DOTS

# ottiene una costante globale con la funzione PHP constant()
::constant(\PHP_VERSION)

Accedere alle proprietà pubbliche e alle costanti di un servizio con @servizio::membro. Se il nome indichi una proprietà o una costante lo decide la sua prima lettera: un'iniziale minuscola significa una proprietà pubblica, una maiuscola significa una costante:

# proprietà pubblica di un servizio (inizia con una lettera minuscola)
@settings::apiUrl

# costante di classe di un servizio (inizia con una lettera maiuscola)
@settings::Version

Le chiamate di metodo si possono concatenare come in PHP. Per semplicità si usa :: invece di ->:

DateTime()::format('Y-m-d')
# PHP: (new DateTime())->format('Y-m-d')

@http.request::getUrl()::getHost()
# PHP: $this->getService('http.request')->getUrl()->getHost()

Potete usare queste espressioni ovunque: nella creazione dei servizi, negli argomenti, nella sezione setup oppure nei parametri:

parameters:
	ipAddress: @http.request::getRemoteAddress()

services:
	database:
		create: DatabaseFactory::create( @anotherService::getDsn() )
		setup:
			- initialize( ::getenv('DB_USER') )

Funzioni speciali

Nei file di configurazione potete usare queste funzioni speciali:

  • not() nega un valore
  • bool(), int(), float(), string() conversione senza perdita nel tipo indicato
  • typed() crea un array di tutti i servizi del tipo indicato
  • tagged() crea un array di tutti i servizi con il tag indicato
services:
	- Foo(
		id: int(::getenv('ProjectId'))
		productionMode: not(%debugMode%)
	)

A differenza della conversione standard di PHP, come (int), la conversione senza perdita solleva un'eccezione per i valori non numerici.

La funzione typed() crea un array di tutti i servizi del tipo indicato (classe o interfaccia). Esclude i servizi che hanno l'autowiring disattivato. Si possono indicare anche più tipi, separati da virgole.

services:
	- BarsDependent( typed(Bar) )

Un array di servizi di un certo tipo si può passare come argomento anche automaticamente, tramite l'autowiring.

La funzione tagged() crea invece un array di tutti i servizi con un determinato tag. Anche qui potete indicare più tag separati da virgole.

services:
	- LoggersDependent( tagged(logger) )

Autowiring

La chiave autowired vi permette di influire sul comportamento dell'autowiring per un determinato servizio. Per i dettagli vedi il capitolo sull'autowiring.

services:
	foo:
		create: Foo
		autowired: false     # il servizio foo è escluso dall'autowiring

Servizi pigri

Il caricamento pigro è una tecnica che rimanda la creazione di un servizio finché non serve davvero. Nella configurazione globale potete attivare la creazione pigra per tutti i servizi in una volta. Per i singoli servizi potete poi sovrascrivere questo comportamento:

services:
	foo:
		create: Foo
		lazy: false

Quando un servizio è definito come pigro, chiedendolo al container DI riceviamo un oggetto proxy speciale. Questo proxy sembra e si comporta esattamente come il servizio reale, ma l'inizializzazione vera e propria (la chiamata del costruttore e quelle del setup) avviene solo al primo accesso a uno qualsiasi dei suoi metodi o delle sue proprietà.

Tenete presente che, poiché il servizio viene creato più tardi, anche gli errori nella sua configurazione si manifestano più tardi. Per esempio, credenziali del database sbagliate non si riveleranno all'avvio dell'applicazione, ma solo alla prima query.

La creazione pigra attenua anche le dipendenze circolari, cioè la situazione in cui il servizio A richiede il servizio B e contemporaneamente B richiede A. Senza di essa il container segnala l'errore Circular reference detected. Con un proxy pigro il servizio A riceve solo un proxy del servizio B, che si inizializza quando viene davvero usato, in un momento in cui A esiste già. Una dipendenza circolare, comunque, segnala una progettazione difettosa, ed è meglio liberarsene.

Il caricamento pigro richiede PHP 8.4 o successivo e funziona solo per i servizi creati istanziando direttamente una classe (per esempio create: Foo), non per quelli creati da un metodo factory. Non si può usare nemmeno per le classi che in ultima analisi estendono una classe interna di PHP. Quando il caricamento pigro non si può applicare, il flag lazy: true viene ignorato in silenzio.

Tag

I tag servono ad aggiungere informazioni supplementari ai servizi. Potete assegnare a un servizio uno o più tag:

services:
	foo:
		create: Foo
		tags:
			- cached

I tag possono anche contenere valori:

services:
	foo:
		create: Foo
		tags:
			logger: monolog.logger.event

Per ottenere tutti i servizi associati a determinati tag potete usare la funzione tagged():

services:
	- LoggersDependent( tagged(logger) )

All'interno del container DI potete ottenere i nomi di tutti i servizi con un determinato tag usando il metodo findByTag():

$names = $container->findByTag('logger');
// $names è un array con i nomi dei servizi come chiavi e i valori dei tag come valori
// per esempio ['foo' => 'monolog.logger.event', ...]

Modalità inject

Usando il flag inject: true si attiva la dependency injection tramite le proprietà pubbliche con l'attributo Inject e tramite i metodi inject*().

services:
	articles:
		create: App\Model\Articles
		inject: true

Per impostazione predefinita la modalità inject è attiva solo per i presenter.

Modifiche ai servizi

Il container DI contiene numerosi servizi aggiunti da estensioni integrate o dell'utente. Potete modificare le definizioni di questi servizi esistenti direttamente nella configurazione. Per esempio potete cambiare la classe del servizio application.application, che di norma è Nette\Application\Application, con un'altra:

services:
	application.application:
		create: MyApplication
		alteration: true

Il flag alteration indica che stiamo solo modificando un servizio esistente. Funge anche da protezione: se il servizio da modificare non esiste, la compilazione fallisce con un'eccezione.

Possiamo anche integrare il setup:

services:
	application.application:
		create: MyApplication
		alteration: true
		setup:
			- '$onStartup[]' = [@resource, init]

Non dovete identificare un servizio con il suo nome interno: potete fare riferimento a esso per tipo. L'esempio precedente si può scrivere anche così:

services:
	@Nette\Application\Application:
		create: MyApplication

Modificando un servizio potremmo voler rimuovere gli argomenti, gli elementi del setup o i tag originali, con la chiave reset:

services:
	application.application:
		create: MyApplication
		alteration: true
		reset:
			arguments: true
			setup: true
			tags: true

Se volete rimuovere un servizio aggiunto da un'estensione, potete farlo così:

services:
	cache.journal: false