Métodos e atributos inject
Neste artigo, focaremos nas diferentes maneiras de passar dependências para presenters no framework Nette.
Compararemos a forma preferida, que é o construtor, com outras opções, como métodos e atributos inject
.
Também para presenters, passar dependências usando o construtor é o caminho
preferido. No entanto, se você criar um ancestral comum do qual outros presenters herdam (por exemplo,
BasePresenter
), e este ancestral também tiver dependências, ocorrerá um problema que chamamos de constructor hell. Isso pode ser
contornado usando caminhos alternativos, que são os métodos e atributos (anotações) inject
.
Métodos inject*()
É uma forma de passar dependências por setter. O nome desses setters
começa com o prefixo inject
. O Nette DI chama automaticamente métodos com esse nome logo após a criação da
instância do presenter e passa a eles todas as dependências necessárias. Portanto, eles devem ser declarados como
public
.
Os métodos inject*()
podem ser considerados como uma extensão do construtor em vários métodos. Graças a isso,
o BasePresenter
pode receber dependências através de outro método e deixar o construtor livre para seus
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;
}
}
Um presenter pode conter qualquer número de métodos inject*()
e cada um pode ter qualquer número de
parâmetros. Eles também são ótimos em casos onde o presenter é composto por traits e cada um deles requer sua própria
dependência.
Atributos Inject
É uma forma de injeção na
propriedade. Basta marcar em quais propriedades injetar, e o Nette DI passa automaticamente as dependências logo após a
criação da instância do presenter. Para poder inseri-las, é necessário declará-las como public
.
Marcamos as propriedades com um atributo: (anteriormente, usava-se a anotação /** @inject */
)
use Nette\DI\Attributes\Inject; // esta linha é importante
class MyPresenter extends Nette\Application\UI\Presenter
{
#[Inject]
public Cache $cache;
}
A vantagem dessa forma de passar dependências era a forma de escrita muito concisa. No entanto, com a chegada da promoção de propriedades do construtor, parece mais fácil usar o construtor.
Por outro lado, essa forma sofre das mesmas desvantagens que a passagem de dependências para propriedades em geral: não temos controle sobre as alterações na variável e, ao mesmo tempo, a variável se torna parte da interface pública da classe, o que é indesejável.