Configuration du conteneur DI

Aperçu des options de configuration du conteneur DI de Nette.

Fichier de configuration

Le conteneur DI de Nette se pilote facilement à l'aide de fichiers de configuration. Ceux-ci s'écrivent habituellement au format NEON. Nous vous recommandons d'utiliser des éditeurs qui prennent en charge ce format.

 decorator: 	Decorator
di: Conteneur DI
extensions: Installer d'autres extensions DI
includes: Inclure des fichiers
parameters: Paramètres
search: Enregistrement automatique des services
services: Services

Pour écrire une chaîne contenant le caractère %, vous devez l'échapper en le doublant en %%.

Paramètres

Dans la configuration, vous pouvez définir des paramètres qui pourront ensuite servir dans les définitions de services. Cela vous permet de rendre la configuration plus lisible ou de centraliser les valeurs susceptibles de changer.

parameters:
	dsn: 'mysql:host=127.0.0.1;dbname=test'
	user: root
	password: secret

Nous faisons référence au paramètre dsn n'importe où dans la configuration par la notation %dsn%. Les paramètres peuvent aussi être utilisés à l'intérieur de chaînes, comme '%wwwDir%/images'.

Les paramètres ne sont pas obligatoirement des chaînes ou des nombres, ils peuvent aussi contenir des tableaux :

parameters:
	mailer:
		host: smtp.example.com
		secure: ssl
		user: franta@gmail.com
	languages: [cs, en, de]

Nous faisons référence à une clé précise par %mailer.user%.

Si votre code (par exemple une classe) a besoin de la valeur d'un paramètre, passez-la-lui. Par exemple dans le constructeur. Il n'existe pas d'objet de configuration global que les classes pourraient interroger pour connaître la valeur d'un paramètre. Ce serait une violation du principe de l'injection de dépendances.

Services

Voir le chapitre distinct.

Decorator

Comment modifier d'un coup plusieurs services d'un certain type ? Par exemple, comment appeler une méthode donnée sur tous les presenters qui héritent d'une classe de base précise ? C'est à cela que sert le decorator.

decorator:
	# pour tous les services qui sont des instances de cette classe ou interface
	App\Presentation\BasePresenter:
		setup:
			- setProjectId(10)       # appeler cette méthode
			- $absoluteUrls = true   # et définir la variable

Le decorator peut aussi servir à poser des tags ou à activer le mode inject.

decorator:
	InjectableInterface:
		tags: [mytag: 1]
		inject: true

DI

Réglages techniques du conteneur DI.

di:
	# afficher le DIC dans la Tracy Bar ?
	debugger: ...        # (bool) détection automatique par défaut (activé si Tracy est présent)

	# types de paramètres que vous n'autowirez jamais
	excluded: ...        # (string[])

	# activer la création lazy des services ?
	lazy: ...            # (bool) false par défaut

	# la classe dont le conteneur DI hérite
	parentClass: ...     # (string) Nette\DI\Container par défaut

Services lazy

Le réglage lazy: true active la création lazy (différée) des services. Cela signifie que les services ne sont pas réellement créés au moment où on les demande au conteneur DI, mais seulement lors de leur première utilisation. Cela peut accélérer le démarrage de l'application et réduire la consommation mémoire, car seuls les services réellement nécessaires à une requête donnée sont créés.

Pour un service précis, la création lazy peut être ajustée.

Les objets lazy ne peuvent être utilisés que pour les classes définies par l'utilisateur, pas pour les classes internes de PHP. Nécessite PHP 8.4 ou plus récent.

Export des métadonnées

La classe du conteneur DI contient aussi beaucoup de métadonnées. Vous pouvez réduire sa taille en réduisant l'export des métadonnées.

di:
	export:
		# exporter les paramètres ?
		parameters: false   # (bool) true par défaut

		# exporter les tags, et lesquels ?
		tags:               # (string[]|bool) tous par défaut
			- event.subscriber

		# exporter les données pour l'autowiring, et lesquelles ?
		types:              # (string[]|bool) toutes par défaut
			- Nette\Database\Connection
			- Symfony\Component\Console\Application

Si vous n'utilisez pas $container->getParameters(), vous pouvez désactiver l'export des paramètres. Vous pouvez en outre n'exporter que les tags dont vous vous servez réellement pour récupérer des services via $container->findByTag(...). Si vous n'appelez pas du tout cette méthode, vous pouvez désactiver complètement l'export des tags avec false.

Vous pouvez réduire nettement les métadonnées de l'autowiring en n'indiquant que les classes que vous demandez réellement avec $container->getByType(). Là encore, si vous n'appelez pas cette méthode (ou seulement dans le fichier bootstrap, par exemple pour obtenir Nette\Application\Application), vous pouvez désactiver complètement l'export des types avec false.

Extensions

Enregistrement d'extensions DI supplémentaires. C'est ainsi que vous ajoutez, par exemple, l'extension DI Dibi\Bridges\Nette\DibiExtension3 sous le nom dibi :

extensions:
	dibi: Dibi\Bridges\Nette\DibiExtension3

Vous la configurez ensuite dans la section dibi :

dibi:
	host: localhost

Vous pouvez aussi ajouter comme extension une classe avec des paramètres :

extensions:
	application: Nette\Bridges\ApplicationDI\ApplicationExtension(%debugMode%, [%appDir%], %tempDir%/cache)

Inclure des fichiers

D'autres fichiers de configuration peuvent être inclus dans la section includes :

includes:
	- parameters.php
	- services.neon
	- presenters.neon

Le nom parameters.php n'est pas une faute de frappe : la configuration peut aussi être écrite dans un fichier PHP qui la renvoie sous forme de tableau :

<?php
return [
	'database' => [
		'main' => [
			'dsn' => 'sqlite::memory:',
		],
	],
];

Si des éléments portant les mêmes clés apparaissent dans plusieurs fichiers de configuration, ils seront écrasés ou, dans le cas des tableaux, fusionnés. Un fichier inclus plus tard a une priorité plus élevée que le précédent. Le fichier dans lequel figure la section includes a une priorité plus élevée que les fichiers qui y sont inclus.

L'enregistrement automatique des services dans le conteneur DI simplifie considérablement le développement. Nette ajoute automatiquement les presenters au conteneur, mais vous pouvez tout aussi facilement y ajouter n'importe quelles autres classes.

Il suffit d'indiquer dans quels répertoires (et sous-répertoires) les classes doivent être recherchées :

search:
	-	in: %appDir%/Forms
	-	in: %appDir%/Model

Si vous n'avez besoin que d'une seule règle de recherche, vous pouvez omettre la liste et écrire ses clés directement sous search :

search:
	in: %appDir%

Habituellement, nous ne voulons cependant pas ajouter absolument toutes les classes et interfaces, nous pouvons donc les filtrer :

search:
	-	in: %appDir%/Forms

		# filtrage par nom de fichier (string|string[])
		files:
			- *Factory.php

		# filtrage par nom de classe (string|string[])
		classes:
			- *Factory

Ou nous pouvons sélectionner les classes qui héritent d'au moins une des classes listées ou qui en implémentent au moins une :

search:
	-	in: %appDir%
		extends:
			- App\*Form
		implements:
			- App\*FormInterface

Vous pouvez également définir des règles d'exclusion à l'aide de masques de noms de classes ou d'ancêtres. Si une classe correspond à une règle d'exclusion, elle ne sera pas ajoutée au conteneur DI :

search:
	-	in: %appDir%
		exclude:
			files: ...
			classes: ...
			extends: ...
			implements: ...

Des tags peuvent être attribués à tous les services enregistrés automatiquement :

search:
	-	in: %appDir%
		tags: ...

Outre les classes, la recherche enregistre aussi les interfaces qui ont une unique méthode create() ou get() – en tant que factories ou accesseurs générés. Les classes pour lesquelles un service du même type est déjà enregistré dans le conteneur sont ignorées, aucun doublon n'est donc créé.

Fusion

Si des éléments portant les mêmes clés apparaissent dans plusieurs fichiers de configuration, ils seront écrasés ou, dans le cas des tableaux, fusionnés. Le fichier inclus plus tard a une priorité plus élevée que le précédent.

config1.neon config2.neon résultat
items:
	- 1
	- 2
items:
	- 3
items:
	- 1
	- 2
	- 3

Pour les tableaux, la fusion peut être empêchée en ajoutant un point d'exclamation après le nom de la clé :

config1.neon config2.neon résultat
items:
	- 1
	- 2
items!:
	- 3
items:
	- 3
version: 3.x