Методи и атрибути за инжектиране
В тази статия ще се съсредоточим върху различните начини за
предаване на зависимости на презентатори в рамката Nette. Ще сравним
предпочитания метод, който е конструкторът, с други възможности, като
например методи и атрибути на inject
.
И за презентаторите предаването на зависимости чрез конструктора е предпочитаният начин. Въпреки това, ако създадете общ предшественик, от който другите презентатори наследяват (например BasePresenter), и този предшественик също има зависимости, възниква проблем, който наричаме конструкторски ад. Той може да бъде заобиколен с помощта на алтернативни методи, които включват инжектиране на методи и атрибути (анотации).
inject*()
Методи
Това е форма на предаване на зависимости с помощта на задаващи елементи. Имената на тези задаващи елементи започват с префикса inject. Nette DI автоматично извиква тези методи веднага след създаването на инстанцията на презентатора и им предава всички необходими зависимости. Следователно те трябва да бъдат декларирани като публични.
inject*()
Методите могат да се разглеждат като вид разширение на
конструктора в множество методи. Благодарение на това BasePresenter
може да приема зависимости чрез друг метод и да остави конструктора
свободен за своите наследници:
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;
}
}
Презентаторът може да съдържа произволен брой методи inject*()
и
всеки от тях може да има произволен брой параметри. Това е чудесно и за
случаите, когато презентаторът е съставен от черти
и всяка от тях изисква своя собствена зависимост.
Inject
Атрибути
Това е форма на инжектиране в свойствата. Достатъчно е да посочите кои свойства трябва да бъдат инжектирани и Nette DI автоматично предава зависимостите веднага след създаването на инстанцията на презентатора. За да ги вмъкнете, е необходимо да ги декларирате като публични.
Свойствата се маркират с атрибут: (преди се използваше анотацията
/** @inject */
)
use Nette\DI\Attributes\Inject; // този ред е важен
class MyPresenter extends Nette\Application\UI\Presenter
{
#[Inject]
public Cache $cache;
}
Предимството на този метод за предаване на зависимостите е, че той е много икономичен за записване. С въвеждането на промоцията на свойствата на конструктора обаче използването на конструктора изглежда по-лесно.
От друга страна, този метод страда от същите недостатъци като предаването на зависимости в свойства като цяло: нямаме контрол върху промените в променливата, а в същото време променливата става част от публичния интерфейс на класа, което е нежелателно.