-
-
Notifications
You must be signed in to change notification settings - Fork 1
Feature Service closures
#[AutowireServiceClosure('id')] инжектирует сервис не напрямую, а как замыкание Closure(): mixed. Вызов замыкания разрешает сервис в момент обращения — отложенный доступ без прокси (аналог Symfony #[AutowireServiceClosure] / service_closure).
Атрибут ставится на параметр конструктора, свойство или сеттер типа \Closure. При autowiring вместо get('id') в член передаётся fn() => $container->get('id'). Сервис не строится, пока замыкание не вызвано; каждый вызов возвращает актуальный экземпляр (для singleton — тот же).
use CloudCastle\DI\Attribute\AutowireServiceClosure;
final class ReportController
{
public function __construct(
#[AutowireServiceClosure(HeavyReportBuilder::class)]
private readonly Closure $builderFactory,
) {}
public function export(): string
{
// HeavyReportBuilder строится только здесь, при первом обращении.
return ($this->builderFactory)()->build();
}
}- Ленивый доступ без прокси-класса — сервис не создаётся, пока не понадобится (экономия на «тяжёлых» зависимостях, редких ветках).
- Разрывает циклы и откладывает дорогие графы без изменения самого сервиса.
- Тип
\Closureв сигнатуре — явный контракт: потребитель видит, что доступ отложенный.
- Точка вызова замыкания менее очевидна, чем прямая зависимость.
- Нельзя типизировать результат замыкания на уровне сигнатуры (
Closure(): Service— только в PHPDoc).
- Тяжёлые/редко используемые сервисы, дорогие для конструирования на каждый запрос.
- Разрыв циклических зависимостей, где полноценный lazy-прокси избыточен.
- Оборачивать в замыкание сервис, который всё равно нужен всегда и сразу — лишняя косвенность.
- Прятать за замыканием обязательную зависимость, скрывая граф.
| Контейнер | Аналог |
|---|---|
| PHP-DI |
DI\get() в фабрике (частично, |
| Symfony |
#[AutowireServiceClosure] / service_closure
|
| Laravel | нет прямого (fn () => app(Id::class) вручную) |
| Pimple |
$pimple->raw() / фабрики |
| Nette | нет прямого ( |
CloudCastle и Symfony дают атрибут-инъекцию сервис-замыкания из коробки; остальные — только вручную.
См. также: Lazy service · Attribute autowiring · Хуки резолвинга.
CloudCastle DI · · PHP 8.1+ · PSR-11
GitHub · Packagist · Releases · Discussions · Сравнение
Исходники Wiki — каталог wiki/ в репозитории (синхронизация через GitHub Actions)
- 🏗️ Архитектура
- ⚡ Быстрый старт
- 📊 Сравнение — 5 аналогов, таблица + победители
- 🧩 Возможности (детально) — каждая фича: принцип, +/−, аналоги
- 🧪 Bootstrap
- 🚀 Compiled container
- 🔗 Contextual binding
- 🤖 Autowiring
- 📄 Конфигурация
- 📖 Справочник конфигурации
- 📂 Сканирование классов
- 🌍 Глобальный реестр
- 🏷️ Теги и декораторы
- 🔗 call(), bind(), hooks
- 🔄 Прототипы, alias, lazy, lazyGhost
- 📋 Справочник API
- 🏭 Фабрики и singleton