Приоритет загрузки зависимостей
Библиотека предоставляет несколько способов определения зависимостей. Важно понимать, в каком порядке они применяются - это помогает избежать неожиданного поведения и правильно настроить контейнер.
🎯 Порядок приоритетов (от высшего к низшему)
- Params для конкретной зависимости
ClassName$argumentNameв разделе params - Alias для конкретной зависимости
ClassName$argumentNameв разделе alias - Params общего вида Общие параметры по имени аргумента
- Alias общего вида Общие псевдонимы по имени класса/интерфейса
- Autowiring в конструктор Автоматическое разрешение по типу аргумента
🧪 Пример, демонстрирующий приоритеты
Конфигурация:
<?php
declare(strict_types=1);
namespace App;
class Example {
public function __construct(
public \stdClass $std_class
) {
}
}
// Создаём различные объекты для тестирования
$std_param = new \stdClass();
$std_param->name = 'params';
$std_param_custom = new \stdClass();
$std_param_custom->name = 'params custom';
$std_alias_custom = new \stdClass();
$std_alias_custom->name = 'alias custom';
$std_alias = new \stdClass();
$std_alias->name = 'alias';
new \Cekta\DI\Compiler(
containers: [Example::class],
params: [
Example::class . '$std_class' => $std_param_custom, // Приоритет 1
\stdClass::class => $std_param, // Приоритет 3
'std_alias_custom' => $std_alias_custom, // Поддержка для приоритета 2
'std_alias' => $std_alias, // Поддержка для приоритета 4
],
alias: [
Example::class . '$std_class' => 'std_alias_custom', // Приоритет 2
\stdClass::class => 'std_alias', // Приоритет 4
],
fqcn: 'App\\Runtime\\Container',
)->compile();
Использование:
<?php
declare(strict_types=1);
namespace App;
$container = new \App\Runtime\Container();
$example = $container->get(Example::class);
echo $example->std_class->name; // Результат: "params custom"
🔍 Как это работает в деталях
При запросе Example::class контейнер ищет зависимость для аргумента $std_class в следующем порядке:
| Приоритет | Способ | В нашем примере |
|---|---|---|
| 1 | Example::class . '$std_class' в params | $std_param_custom |
| 2 | Example::class . '$std_class' в alias | Ссылается на 'std_alias_custom' |
| 3 | Общие params для \stdClass::class | $std_param |
| 4 | Общие alias для \stdClass::class | Ссылается на std_alias |
| 5 | Autowiring | Попытка создать \stdClass автоматически |
Итог: Выигрывает наивысший приоритет - параметр для конкретной зависимости.
⚠️ Важные замечания
- Конкретные настройки всегда побеждают - используйте ClassName$argument для точного контроля
- Порядок в конфигурации не имеет значения - приоритеты фиксированы
- Autowiring - последний вариант - используется только если нет других указаний
- Проверка на этапе компиляции - библиотека предупредит о невозможности разрешить зависимость
Понимание приоритетов позволяет гибко настраивать зависимости, переопределяя их там, где нужно, и полагаясь на автоматику в остальных случаях.