Методи та атрибути ін'єкції
У цій статті ми розглянемо різні способи передачі
залежностей доповідачам у фреймворку 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;
}
Перевагою такого способу передачі залежностей була дуже економна форма запису. Однак, із запровадженням популяризації властивостей конструктора, використання конструктора видається простішим.
З іншого боку, цей спосіб страждає тими ж недоліками, що і передача залежностей у властивості взагалі: ми не маємо контролю над змінами змінної, і в той же час змінна стає частиною публічного інтерфейсу класу, що є небажаним.