Методы и атрибуты инъекции
На конкретных примерах мы рассмотрим возможности передачи
зависимостей ведущим и объясним методы inject
и
атрибуты/аннотации.
inject*()
Методы
В презентаторе, как и в любом другом коде, предпочтительным способом
передачи зависимостей является использование конструктора.
Однако если презентер наследуется от общего предка (например,
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 автоматически передаст зависимости свойствам, аннотированным таким образом в презентере, как только экземпляр будет создан.
Этот метод имеет те же недостатки, что и передача зависимостей в публичное свойство. Он используется в презентерах, поскольку не усложняет код и требует минимального набора текста.