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.