Nette Documentation Preview

syntax
Métodos y atributos de inyección
********************************

.[perex]
En este artículo, nos centraremos en varias formas de pasar dependencias a los presentadores en el framework Nette. Compararemos el método preferido, que es el constructor, con otras opciones como los métodos y atributos de `inject`.

En el caso de los presentadores, el método preferido es pasar las dependencias mediante el [constructor |dependency-injection:passing-dependencies#Constructor Injection].
Sin embargo, si creas un ancestro común del que heredan otros presentadores (por ejemplo, BasePresenter), y este ancestro también tiene dependencias, surge un problema, que llamamos [constructor hell |dependency-injection:passing-dependencies#Constructor hell].
Esto puede evitarse utilizando métodos alternativos, que incluyen inyectar métodos y atributos (anotaciones).


`inject*()` Métodos .[#toc-inject-methods]
==========================================

Se trata de una forma de pasar dependencias mediante [setters |dependency-injection:passing-dependencies#Setter Injection]. Los nombres de estos setters comienzan con el prefijo inject.
Nette DI llama automáticamente a estos métodos con nombre inmediatamente después de crear la instancia del presentador y les pasa todas las dependencias necesarias. Por lo tanto, deben declararse como públicos.

`inject*()` pueden considerarse como una especie de extensión del constructor en varios métodos. Gracias a esto, el `BasePresenter` puede tomar dependencias a través de otro método y dejar el constructor libre para sus descendientes:

```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;
	}
}
```

El presentador puede contener cualquier número de métodos `inject*()`, y cada uno puede tener cualquier número de parámetros. Esto también es genial para los casos en que el presentador [se compone de rasgos |presenter-traits], y cada uno de ellos requiere su propia dependencia.


`Inject` Atributos .[#toc-inject-attributes]
============================================

Esta es una forma de inyección [en propiedades |dependency-injection:passing-dependencies#Property Injection]. Basta con indicar qué propiedades deben inyectarse, y Nette DI pasa automáticamente las dependencias inmediatamente después de crear la instancia del presentador. Para insertarlas, es necesario declararlas como públicas.

Las propiedades se marcan con un atributo: (antes se utilizaba la anotación `/** @inject */`)

```php
use Nette\DI\Attributes\Inject; // esta línea es importante

class MyPresenter extends Nette\Application\UI\Presenter
{
	#[Inject]
	public Cache $cache;
}
```

La ventaja de este método de pasar dependencias era su forma de notación muy económica. Sin embargo, con la introducción de la [promoción de propiedades |https://blog.nette.org/es/php-8-0-vision-completa-de-las-novedades#toc-constructor-property-promotion] del constructor, el uso del constructor parece más sencillo.

Por otro lado, este método adolece de los mismos defectos que pasar dependencias a propiedades en general: no tenemos control sobre los cambios en la variable y, al mismo tiempo, la variable pasa a formar parte de la interfaz pública de la clase, lo cual no es deseable.


{{sitename: Buenas prácticas}}

Métodos y atributos de inyección

En este artículo, nos centraremos en varias formas de pasar dependencias a los presentadores en el framework Nette. Compararemos el método preferido, que es el constructor, con otras opciones como los métodos y atributos de inject.

En el caso de los presentadores, el método preferido es pasar las dependencias mediante el constructor. Sin embargo, si creas un ancestro común del que heredan otros presentadores (por ejemplo, BasePresenter), y este ancestro también tiene dependencias, surge un problema, que llamamos constructor hell. Esto puede evitarse utilizando métodos alternativos, que incluyen inyectar métodos y atributos (anotaciones).

inject*() Métodos

Se trata de una forma de pasar dependencias mediante setters. Los nombres de estos setters comienzan con el prefijo inject. Nette DI llama automáticamente a estos métodos con nombre inmediatamente después de crear la instancia del presentador y les pasa todas las dependencias necesarias. Por lo tanto, deben declararse como públicos.

inject*() pueden considerarse como una especie de extensión del constructor en varios métodos. Gracias a esto, el BasePresenter puede tomar dependencias a través de otro método y dejar el constructor libre para sus descendientes:

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;
	}
}

El presentador puede contener cualquier número de métodos inject*(), y cada uno puede tener cualquier número de parámetros. Esto también es genial para los casos en que el presentador se compone de rasgos, y cada uno de ellos requiere su propia dependencia.

Inject Atributos

Esta es una forma de inyección en propiedades. Basta con indicar qué propiedades deben inyectarse, y Nette DI pasa automáticamente las dependencias inmediatamente después de crear la instancia del presentador. Para insertarlas, es necesario declararlas como públicas.

Las propiedades se marcan con un atributo: (antes se utilizaba la anotación /** @inject */)

use Nette\DI\Attributes\Inject; // esta línea es importante

class MyPresenter extends Nette\Application\UI\Presenter
{
	#[Inject]
	public Cache $cache;
}

La ventaja de este método de pasar dependencias era su forma de notación muy económica. Sin embargo, con la introducción de la promoción de propiedades del constructor, el uso del constructor parece más sencillo.

Por otro lado, este método adolece de los mismos defectos que pasar dependencias a propiedades en general: no tenemos control sobre los cambios en la variable y, al mismo tiempo, la variable pasa a formar parte de la interfaz pública de la clase, lo cual no es deseable.