-
-
Notifications
You must be signed in to change notification settings - Fork 1
Factories and singleton
flowchart TD
Set["set(id, callable)"] --> Def[(definitions)]
Get1["get(id) первый раз"] --> Call[вызов фабрики с container]
Call --> Inst[экземпляр]
Inst --> Cache[(resolved singleton)]
Get2["get(id) повторно"] --> Cache
Make["make(id)"] --> Call
Make -.->|не пишет| Cache
Decorate["decorate(id)"] --> Clear[сброс resolved id]
Clear --> Def
$container->set('mailer', new Mailer($dsn));Если передан callable, он вызывается один раз; результат кэшируется до следующего set() или decorate():
use CloudCastle\DI\Contract\ContainerInterface;
$container->set(
'repository',
static function (ContainerInterface $container): UserRepository {
return new UserRepository($container->get('pdo'));
},
);В фабрику передаётся сам контейнер — так строятся цепочки зависимостей.
set() + фабрика |
autowiring | |
|---|---|---|
| Контроль создания | полный | по конструктору |
| Id | любая строка | обычно FQCN |
| Циклы | не отслеживаются | ContainerException |
| Приоритет | выше autowiring | ниже явного set()
|
Можно комбинировать: scan + явные set() для интерфейсов.
- замыкание
fn () => ...илиfunction () { ... }; - объект с
__invoke; - first-class callable
$factory->create(...); - массив
[$object, 'method'](не путать с data-массивом сервиса).
set() с тем же id сбрасывает ранее созданный singleton:
$container->set('token', 'dev');
$container->set('token', 'prod');
$container->get('token'); // 'prod'autowire(FQCN) также сбрасывает кэш для этого id.
set('id', null) не распознаётся как регистрация из-за isset() в PHP.
Такой результат не кэшируется — при каждом get() создание повторяется.
A → B → A через set() не обнаруживаются автоматически. Возможен бесконечный цикл или переполнение стека.
При autowiring циклы обнаруживаются — см. Autowiring.
$container->set('db', static fn () => new PDO(...));
$container->hasDefinition('db'); // true
$container->has('db'); // true
// get() ещё не вызывался — PDO не создан
$pdo = $container->get('db');
$container->has('db'); // true (definition + resolved)С autowiring:
$container->enableAutowiring();
$container->has(App\Service\UserService::class); // true
$container->hasDefinition(App\Service\UserService::class); // false
$container->autowire(App\Service\UserService::class);
$container->hasDefinition(App\Service\UserService::class); // true$container->set('dto', static fn () => new stdClass());
$a = $container->make('dto');
$b = $container->make('dto'); // новый объект при каждом вызовеmake() не заполняет singleton-кэш; декораторы применяются. Подробнее — Прототипы, alias и lazy.
$container->set('app.clock', $clock);
$container->alias(ClockInterface::class, 'app.clock');$container->set('heavy', $container->lazy(HeavyService::class));
$lazy = $container->get('heavy');
$service = $lazy->getValue(); // первый get() внутри LazyServiceCloudCastle DI · PHP 8.1+ · PSR-11
GitHub · Packagist · Releases · Discussions · Сравнение
Исходники Wiki — каталог wiki/ в репозитории (синхронизация через GitHub Actions)
- 🏗️ Архитектура
- ⚡ Быстрый старт
- 📊 Сравнение — 5 аналогов, таблица + победители
- 🧪 Bootstrap
- 🚀 Compiled container
- 🤖 Autowiring
- 📄 Конфигурация
- 📖 Справочник конфигурации
- 📂 Сканирование классов
- 🌍 Глобальный реестр
- 🏷️ Теги и декораторы
- 🔗 call(), bind(), hooks
- 🔄 Прототипы, alias, lazy
- 📋 Справочник API
- 🏭 Фабрики и singleton