-
-
Notifications
You must be signed in to change notification settings - Fork 1
Feature Factories
Фабрика — callable, создающий сервис лениво. По умолчанию результат кэшируется как singleton: один экземпляр на весь контейнер.
set($id, $factory) кладёт callable в definitions. При первом get($id) контейнер вызывает фабрику (передавая сам контейнер, чтобы фабрика могла достать зависимости), сохраняет результат в resolved и возвращает. Все последующие get($id) возвращают закэшированный экземпляр без повторного вызова фабрики.
$c->set(PaymentGateway::class, function (Container $c) {
return new PaymentGateway(
$c->get(HttpClient::class),
$c->get('config.stripe_key'),
);
});
$a = $c->get(PaymentGateway::class);
$b = $c->get(PaymentGateway::class);
$a === $b; // true — singletonГотовый объект тоже можно зарегистрировать (set($id, $object)) — тогда он просто отдаётся как есть.
- Ленивость: сервис создаётся только при первом обращении — пустой контейнер лёгкий, старт приложения быстрый.
- Полный контроль: в фабрике можно собрать сложную инициализацию, которую autowiring не покроет.
- Singleton по умолчанию — то, что нужно для stateless-сервисов (клиенты, репозитории).
- Фабрику надо писать руками — для простых классов лишний boilerplate (используйте autowiring).
- Singleton хранит состояние между вызовами — опасно для изменяемых объектов в долгоживущих процессах (worker, Swoole).
- Держать фабрики «тонкими»: только сборка зависимостей, без бизнес-логики и побочных эффектов.
- Для stateless-сервисов — singleton (по умолчанию); для сервисов с состоянием запроса —
make()или scope. - Типизировать возвращаемое значение фабрики (
fn (): PaymentGateway => …) — читаемость и статанализ.
- Выполнять в фабрике тяжёлые side-effects (запросы к БД, HTTP) — фабрика должна строить, а не работать.
- Кэшировать как singleton объект, зависящий от текущего запроса/пользователя, в долгоживущем процессе.
| Контейнер | Аналог |
|---|---|
| PHP-DI |
factory() / автоматический singleton; factory()->parameter()
|
| Symfony | определение сервиса shared: true (по умолчанию) |
| Laravel |
bind() (новый экземпляр) vs singleton() (кэш) |
| Pimple |
$c['id'] = fn () => … (singleton); $c->factory() для не-singleton |
| Nette | сервисы в конфиге — singleton по умолчанию |
Паритет: фабрики + singleton-кэш есть во всех контейнерах.
См. также: Прототипы · Smart cache / TTL.
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