Métodos de Injeção e Atributos

Usando exemplos específicos, analisaremos as possibilidades de passar dependências aos apresentadores e explicaremos os métodos e atributos/anotações inject.

inject*() Métodos

No apresentador, como em qualquer outro código, a forma preferida de passar as dependências é usando o construtor. Entretanto, se o apresentador herdar de um ancestral comum (por exemplo, BasePresenter), é melhor usar os métodos do inject*() nesse ancestral. É um caso especial de um compositor, onde o método começa com um prefixo inject. Isto porque mantemos o construtor livre para os descendentes:

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

A diferença básica de um setter é que a Nette DI chama automaticamente os métodos assim nomeados nos apresentadores assim que a instância é criada, passando todas as dependências necessárias para eles. Um apresentador pode conter vários métodos inject*() e cada método pode ter qualquer número de parâmetros.

Se passássemos as dependências aos antepassados através de seus construtores, teríamos que obter suas dependências em todos os descendentes e passá-las para parent::__construct(), o que complica o código:

abstract class BasePresenter extends Nette\Application\UI\Presenter
{
	private Foo $foo;

	public function __construct(Foo $foo)
	{
		$this->foo = $foo;
	}
}

class MyPresenter extends BasePresenter
{
	private Bar $bar;

	public function __construct(Foo $foo, Bar $bar)
	{
		parent::__construct($foo); // esta é uma complicação
		$this->bar = $bar;
	}
}

Os métodos inject*() também são úteis nos casos em que o apresentador é composto de traços e cada um deles requer sua própria dependência.

Também é possível utilizar a anotação @inject, mas é importante ter em mente que o encapsulamento quebra.

Inject Anotações

Esta é uma passagem automática da dependência para a variável de membro público do apresentador, que é anotada com @inject no comentário da documentação. O tipo também pode ser especificado no comentário da documentação se você estiver usando PHP inferior a 7,4.

class MyPresenter extends Nette\Application\UI\Presenter
{
	/** @inject */
	public Cache $cache;
}

Desde o PHP 8.0, uma propriedade pode ser marcada com um atributo Inject:

use Nette\DI\Attributes\Inject;

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

Novamente, a Nette DI passará automaticamente as dependências às propriedades anotadas desta forma no apresentador, assim que a instância for criada.

Este método tem as mesmas deficiências que a passagem de dependências para um bem público. É utilizado no apresentador porque não complica o código e requer apenas um mínimo de digitação.