Metode in atributi inject
V tem članku se bomo osredotočili na različne načine posredovanja odvisnosti v presenterje v ogrodju
Nette. Primerjali bomo prednostni način, ki je konstruktor, z drugimi možnostmi, kot so metode in atributi
inject
.
Tudi za presenterje velja, da je posredovanje odvisnosti s pomočjo konstruktorja
prednostna pot. Če pa ustvarjate skupnega prednika, od katerega dedujejo drugi presenterji (npr. BasePresenter
), in
ta prednik ima tudi odvisnosti, nastane problem, ki mu pravimo constructor hell. Temu se lahko
izognemo z alternativnimi potmi, ki jih predstavljajo metode in atributi (anotacije) inject
.
Metode inject*()
Gre za obliko posredovanja odvisnosti s setterjem. Ime teh setterjev
se začne s predpono inject
. Nette DI tako poimenovane metode samodejno pokliče takoj po ustvarjanju instance
presenterja in jim posreduje vse zahtevane odvisnosti. Zato morajo biti deklarirane kot public.
Metode inject*()
lahko štejemo za nekakšno razširitev konstruktorja v več metod. Zahvaljujoč temu lahko
BasePresenter
prevzame odvisnosti prek druge metode in pusti konstruktor prost za svoje potomce:
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;
}
}
Presenter lahko vsebuje poljubno število metod inject*()
in vsaka lahko ima poljubno število parametrov.
Odlično se obnesejo tudi v primerih, ko je presenter sestavljen iz lastnosti (trait) in vsaka od njih zahteva svojo
odvisnost.
Atributi Inject
Gre za obliko injiciranja v lastnost. Dovolj je označiti, v katere spremenljivke naj se injicira, in Nette DI samodejno posreduje odvisnosti takoj po ustvarjanju instance presenterja. Da jih lahko vstavi, jih je treba deklarirati kot public.
Lastnosti označimo z atributom: (prej se je uporabljala anotacija /** @inject */
)
use Nette\DI\Attributes\Inject; // ta vrstica je pomembna
class MyPresenter extends Nette\Application\UI\Presenter
{
#[Inject]
public Cache $cache;
}
Prednost tega načina posredovanja odvisnosti je bila zelo varčna oblika zapisa. Vendar pa se z uvedbo constructor property promotion zdi lažje uporabiti konstruktor.
Nasprotno pa ta način trpi za enakimi pomanjkljivostmi kot posredovanje odvisnosti v lastnosti (properties) na splošno: nimamo nadzora nad spremembami v spremenljivki in hkrati spremenljivka postane del javnega vmesnika razreda, kar je nezaželeno.