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.