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.