Configuración del contenedor DI
Resumen de las opciones de configuración del contenedor DI de Nette.
Archivo de configuración
El contenedor DI de Nette se controla fácilmente con archivos de configuración. Normalmente se escriben en el formato NEON. Para editarlos recomendamos editores con soporte para este formato.
decorator: Decorator
di: Contenedor DI
extensions: Instalación de extensiones DI adicionales
includes: Inclusión de archivos
parameters: Parámetros
search: Registro automático de servicios
services: Servicios
Para escribir una cadena que contenga el carácter %, hay que escaparlo duplicándolo a
%%.
Parámetros
En la configuración puede definir parámetros que después se pueden usar como parte de las definiciones de los servicios. Eso le permite aclarar la configuración o centralizar valores que pueden cambiar.
parameters:
dsn: 'mysql:host=127.0.0.1;dbname=test'
user: root
password: secret
Al parámetro dsn nos referimos en cualquier lugar de la configuración con la notación %dsn%. Los
parámetros se pueden usar también dentro de cadenas como '%wwwDir%/images'.
Los parámetros no tienen por qué ser solo cadenas o números: también pueden contener arrays:
parameters:
mailer:
host: smtp.example.com
secure: ssl
user: franta@gmail.com
languages: [cs, en, de]
A una clave concreta nos referimos como %mailer.user%.
Si su código (p. ej. una clase) necesita el valor de un parámetro, páseselo a la clase. Por ejemplo, en el constructor. No existe ningún objeto de configuración global al que las clases puedan preguntar por los valores de los parámetros. Eso sería una violación del principio de la inyección de dependencias.
Servicios
Véase el capítulo aparte.
Decorator
¿Cómo modificar de una vez varios servicios de un determinado tipo? Por ejemplo, ¿cómo llamar a un método concreto en todos los presenters que heredan de una determinada clase base? Para eso está el decorator.
decorator:
# para todos los servicios que sean instancias de esta clase o interfaz
App\Presentation\BasePresenter:
setup:
- setProjectId(10) # llama a este método
- $absoluteUrls = true # y establece la variable
El decorator se puede usar también para poner etiquetas o para activar el modo inject.
decorator:
InjectableInterface:
tags: [mytag: 1]
inject: true
DI
Ajustes técnicos del contenedor DI.
di:
# ¿mostrar el DIC en la Tracy Bar?
debugger: ... # (bool) de forma predeterminada se autodetecta (activado si Tracy está presente)
# tipos de parámetros que nunca se autoconectan
excluded: ... # (string[])
# ¿activar la creación lazy de los servicios?
lazy: ... # (bool) el valor predeterminado es false
# la clase de la que hereda el contenedor DI
parentClass: ... # (string) el valor predeterminado es Nette\DI\Container
Servicios lazy
El ajuste lazy: true activa la creación lazy (diferida) de los servicios. Eso significa que los servicios no se
crean realmente en el momento en que se piden al contenedor DI, sino solo en el momento de su primer uso. Esto puede acelerar el
arranque de la aplicación y reducir el consumo de memoria, porque solo se crean los servicios realmente necesarios para cada
petición.
Para un servicio concreto, la creación lazy se puede ajustar.
Los objetos lazy solo se pueden usar para clases definidas por el usuario, no para clases internas de PHP. Requiere PHP 8.4 o superior.
Exportación de metadatos
La clase del contenedor DI contiene también muchos metadatos. Puede reducir su tamaño reduciendo la exportación de metadatos.
di:
export:
# ¿exportar los parámetros?
parameters: false # (bool) el valor predeterminado es true
# ¿exportar las etiquetas y cuáles?
tags: # (string[]|bool) de forma predeterminada, todas
- event.subscriber
# ¿exportar los datos para el autowiring y cuáles?
types: # (string[]|bool) de forma predeterminada, todos
- Nette\Database\Connection
- Symfony\Component\Console\Application
Si no usa $container->getParameters(), puede desactivar la exportación de parámetros. Además, puede exportar
solo las etiquetas que realmente usa para obtener servicios con $container->findByTag(...). Si no llama a ese
método en absoluto, puede desactivar por completo la exportación de etiquetas con false.
Puede reducir considerablemente los metadatos para el autowiring enumerando solo las clases que realmente pide con
$container->getByType(). De nuevo, si no llama a ese método (o lo llama solo en el archivo de bootstrap, p. ej. para obtener
Nette\Application\Application), puede desactivar por completo la exportación de tipos con false.
Extensiones
Registro de extensiones DI adicionales. Así se añade, por ejemplo, la extensión DI
Dibi\Bridges\Nette\DibiExtension3 bajo el nombre dibi:
extensions:
dibi: Dibi\Bridges\Nette\DibiExtension3
Después la configura en la sección dibi:
dibi:
host: localhost
También puede añadir como extensión una clase con parámetros:
extensions:
application: Nette\Bridges\ApplicationDI\ApplicationExtension(%debugMode%, [%appDir%], %tempDir%/cache)
Inclusión de archivos
Se pueden incluir archivos de configuración adicionales en la sección includes:
includes:
- parameters.php
- services.neon
- presenters.neon
El nombre parameters.php no es una errata; la configuración también se puede escribir en un archivo PHP que la
devuelva como array:
<?php
return [
'database' => [
'main' => [
'dsn' => 'sqlite::memory:',
],
],
];
Si en varios archivos de configuración aparecen elementos con las mismas claves, se sobrescriben o, en el caso de los arrays,
se fusionan. Un archivo incluido después tiene mayor prioridad que el anterior. El archivo en el que
está la sección includes tiene mayor prioridad que los archivos incluidos en él.
Search
El registro automático de servicios en el contenedor DI simplifica notablemente el desarrollo. Nette añade los presenters al contenedor automáticamente, pero puede añadir con facilidad cualquier otra clase.
Basta con indicar en qué directorios (y subdirectorios) deben buscarse las clases:
search:
- in: %appDir%/Forms
- in: %appDir%/Model
Si solo necesita una única regla de búsqueda, puede omitir la lista y escribir sus claves directamente bajo
search:
search:
in: %appDir%
Normalmente, sin embargo, no queremos añadir absolutamente todas las clases e interfaces, así que podemos filtrarlas:
search:
- in: %appDir%/Forms
# filtrado por nombre de archivo (string|string[])
files:
- *Factory.php
# filtrado por nombre de clase (string|string[])
classes:
- *Factory
O podemos elegir las clases que heredan o implementan al menos una de las clases indicadas:
search:
- in: %appDir%
extends:
- App\*Form
implements:
- App\*FormInterface
También puede definir reglas de exclusión mediante máscaras de nombres de clase o de antecesores. Si una clase encaja con una regla de exclusión, no se añadirá al contenedor DI:
search:
- in: %appDir%
exclude:
files: ...
classes: ...
extends: ...
implements: ...
A todos los servicios registrados automáticamente se les pueden asignar etiquetas:
search:
- in: %appDir%
tags: ...
Además de las clases, la búsqueda registra también las interfaces que tienen un único método create() o
get(), como factories o accessors generados. Las
clases para las que ya hay registrado en el contenedor un servicio del mismo tipo se omiten, así que no se crean duplicados.
Fusión
Si en varios archivos de configuración aparecen elementos con las mismas claves, se sobrescriben o, en el caso de los arrays, se fusionan. El archivo incluido después tiene mayor prioridad que el anterior.
| config1.neon | config2.neon | resultado |
|---|---|---|
|
|
|
En el caso de los arrays se puede impedir la fusión añadiendo un signo de exclamación tras el nombre de la clave:
| config1.neon | config2.neon | resultado |
|---|---|---|
|
|
|