Jaké jsou best practice pro předávání závislostí presenterům, komponentám a jiným službám v Nette?
Nejprve: nezávisle na frameworku nebo typu tříd platí vždy tohle:
- povinné závislosti předávat konstruktorem
- volitelné buď samostatnou metodou, nebo též konstruktorem
Tečka.
Nicméně existuje případ, kdy je předávání závislostí konstruktorem
problematické, tzv. constructor hell,
tedy situace, kdy předáváme závislosti konstruktorem určité třídě a
zároveň jejímu potomkovi. Tohle nastává často u presenterů, kde je
právě zvykem mít nějaký BasePresenter. Jako workaround dává DI kontejner
v Nette možnost použít v BasePresenteru místo konstruktoru metodu nazvanou
injectBase()
(případně jakkoliv jinak, jen musí začínat na
inject
).
Jde o workaround pro base presentery, takže v jiných situacích metody inject nepoužívejte.
Dále předávání závislostí přes konstruktory nebo jiné metody je
otravné v tom, že musíte napsat nějaký rutinní kód. Nutnost psát
rutinní kód vždy ukazuje na slabé místo samotného jazyka, jedna ze šancí na
zjednodušení byla zamítnuta, nicméně některé IDE ho umí vygenerovat
a taktéž DI kontejner ve frameworku nabízí zkratku v podobě
@inject
anotací. Public (!) proměnnou doplníte anotací např.
/** @var Model\UserFacade @inject */
a framework sám do ní
vloží službu a vyhnete se psaní konstruktoru nebo inject metody.
Protože to není čisté řešení, funguje opět jen pro presentery. Používání anotací rozhodně není best practice, ale je to sakra pohodlné.
Doporučuji podívat se na přednášku Filipa Procházky a přečíst článek Vojty Dobeše Tvorba komponent s využitím autowiringu.