Nette Documentation Preview

syntax
Métodos de Injeção e Atributos
******************************

.[perex]
Neste artigo, vamos nos concentrar em várias formas de passar dependências aos apresentadores na estrutura da Nette. Vamos comparar o método preferido, que é o construtor, com outras opções como `inject` métodos e atributos.

Também para os apresentadores, a passagem de dependências utilizando o [construtor |dependency-injection:passing-dependencies#Constructor Injection] é a forma preferida.
Entretanto, se você criar um ancestral comum do qual outros apresentadores herdam (por exemplo, BasePresenter), e este ancestral também tiver dependências, surge um problema, ao qual chamamos de [construtor inferno |dependency-injection:passing-dependencies#Constructor hell].
Isto pode ser contornado usando métodos alternativos, que incluem métodos de injeção e atributos (anotações).


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

Esta é uma forma de passagem de dependência utilizando [setters |dependency-injection:passing-dependencies#Setter Injection]. Os nomes desses setters começam com o prefixo injetar.
Nette DI chama automaticamente tais métodos nomeados imediatamente após criar a instância apresentadora e passa todas as dependências necessárias a eles. Portanto, eles devem ser declarados como públicos.

`inject*()` métodos podem ser considerados como uma espécie de extensão do construtor em múltiplos métodos. Graças a isso, o `BasePresenter` pode levar dependências através de outro método e deixar o construtor livre para seus descendentes:

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

O apresentador pode conter qualquer número de métodos `inject*()`, e cada um pode ter qualquer número de parâmetros. Isto também é ótimo para casos onde o apresentador é [composto de traços |presenter-traits], e cada um deles requer sua própria dependência.


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

Esta é uma forma de [injeção em propriedades |dependency-injection:passing-dependencies#Property Injection]. Basta indicar quais propriedades devem ser injetadas, e a Nette DI passa automaticamente as dependências imediatamente após a criação da instância apresentadora. Para inseri-las, é necessário declará-las como públicas.

As propriedades são marcadas com um atributo: (anteriormente, foi utilizada a anotação `/** @inject */`)

```php
use Nette\DI\Attributes\Inject; // esta linha é importante

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

A vantagem deste método de passar dependências foi sua forma muito econômica de notação. Entretanto, com a introdução da [promoção da propriedade do construtor |https://blog.nette.org/pt/php-8-0-visao-geral-completa-das-noticias#toc-constructor-property-promotion], o uso do construtor parece mais fácil.

Por outro lado, este método sofre das mesmas deficiências que a passagem de dependências para propriedades em geral: não temos controle sobre as mudanças na variável e, ao mesmo tempo, a variável se torna parte da interface pública da classe, o que é indesejável.


{{sitename: Melhores Práticas}}

Métodos de Injeção e Atributos

Neste artigo, vamos nos concentrar em várias formas de passar dependências aos apresentadores na estrutura da Nette. Vamos comparar o método preferido, que é o construtor, com outras opções como inject métodos e atributos.

Também para os apresentadores, a passagem de dependências utilizando o construtor é a forma preferida. Entretanto, se você criar um ancestral comum do qual outros apresentadores herdam (por exemplo, BasePresenter), e este ancestral também tiver dependências, surge um problema, ao qual chamamos de construtor inferno. Isto pode ser contornado usando métodos alternativos, que incluem métodos de injeção e atributos (anotações).

inject*() Métodos

Esta é uma forma de passagem de dependência utilizando setters. Os nomes desses setters começam com o prefixo injetar. Nette DI chama automaticamente tais métodos nomeados imediatamente após criar a instância apresentadora e passa todas as dependências necessárias a eles. Portanto, eles devem ser declarados como públicos.

inject*() métodos podem ser considerados como uma espécie de extensão do construtor em múltiplos métodos. Graças a isso, o BasePresenter pode levar 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;
	}
}

O apresentador pode conter qualquer número de métodos inject*(), e cada um pode ter qualquer número de parâmetros. Isto também é ótimo para casos onde o apresentador é composto de traços, e cada um deles requer sua própria dependência.

Inject Atributos

Esta é uma forma de injeção em propriedades. Basta indicar quais propriedades devem ser injetadas, e a Nette DI passa automaticamente as dependências imediatamente após a criação da instância apresentadora. Para inseri-las, é necessário declará-las como públicas.

As propriedades são marcadas com um atributo: (anteriormente, foi utilizada 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 deste método de passar dependências foi sua forma muito econômica de notação. Entretanto, com a introdução da promoção da propriedade do construtor, o uso do construtor parece mais fácil.

Por outro lado, este método sofre das mesmas deficiências que a passagem de dependências para propriedades em geral: não temos controle sobre as mudanças na variável e, ao mesmo tempo, a variável se torna parte da interface pública da classe, o que é indesejável.