Методи та атрибути ін'єкції
На конкретних прикладах ми розглянемо можливості передачі
залежностей доповідачам і пояснимо методи та атрибути/анотації
inject
.
inject*()
Методи
У presenter, як і в будь-якому іншому коді, найкращим способом передачі
залежностей є використання конструктора.
Однак, якщо presenter успадковується від спільного предка (наприклад,
BasePresenter
), краще використовувати методи inject*()
у цьому
предку. Це окремий випадок сеттера, де метод починається з префікса
inject
. Це робиться тому, що ми залишаємо конструктор вільним для
нащадків:
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;
}
}
Основна відмінність від сетера полягає в тому, що Nette DI автоматично
викликає методи з такими іменами в презентерах одразу після створення
екземпляра, передаючи їм усі необхідні залежності. Презентер може
містити кілька методів inject*()
, і кожен метод може мати будь-яку
кількість параметрів.
Впровадження через конструктор не рекомендується для загальних
предків, оскільки під час успадкування необхідно отримати залежність
усіх батьківських презентерів і передавати їх у parent::__construct()
:
abstract class BasePresenter extends Nette\Application\UI\Presenter
{
private Foo $foo;
public function __construct(Foo $foo)
{
$this->foo = $foo;
}
}
class MyPresenter extends BasePresenter
{
private Bar $bar;
public function __construct(Foo $foo, Bar $bar)
{
parent::__construct($foo); // це ускладнення
$this->bar = $bar;
}
}
Методи inject*()
також корисні у випадках, коли презентер складається з ознак, і кожна з них
вимагає своєї власної залежності.
Також можна використовувати анотацію @inject
, але при цьому
важливо пам'ятати, що інкапсуляція порушується.
Анотації Inject
У цьому випадку властивість анотується як @inject
у коментарі
документації. Тип також може бути вказано в коментарі до документації,
якщо ви використовуєте PHP нижче 7.4.
class MyPresenter extends Nette\Application\UI\Presenter
{
/** @inject */
public Cache $cache;
}
Починаючи з версії PHP 8.0, властивість може бути позначена атрибутом
Inject
:
use Nette\DI\Attributes\Inject;
class MyPresenter extends Nette\Application\UI\Presenter
{
#[Inject]
public Cache $cache;
}
Знову ж таки, Nette DI автоматично передасть залежності властивостям, анотованим таким чином у презентері, щойно екземпляр буде створено.
Цей метод має ті самі недоліки, що й передача залежностей у публічну властивість. Він використовується в презентерах, оскільки не ускладнює код і вимагає мінімального набору тексту.