Skip to content

Feature Contextual

github-actions[bot] edited this page Jul 8, 2026 · 1 revision

🎯 Contextual binding

← Возможности · Главная · Сравнение

Разным потребителям — разные реализации одного контракта: when(A)->needs(X)->give(Y). Туториал — Contextual-binding.

Принцип работы

ContextualBindingSupport хранит правила «для потребителя A зависимость X разрешать как Y». При autowiring класса A, встретив параметр типа X, контейнер сначала проверяет контекстное правило и подставляет Y вместо глобальной привязки.

$c->when(ReportController::class)
  ->needs(LoggerInterface::class)
  ->give(AuditLogger::class);

$c->when(HealthController::class)
  ->needs(LoggerInterface::class)
  ->give(NullLogger::class);

// ReportController получит AuditLogger, HealthController — NullLogger

contextualGive() / exportContextualBindings() дают программный доступ к правилам.

Плюсы

  • Точечная подмена без глобального переопределения интерфейса.
  • Решает частый случай: один контракт, разные реализации по месту (аудит vs no-op логгер, разные диски/очереди).
  • Читается декларативно.

Минусы

  • Много контекстных правил → сложнее держать в голове весь граф.
  • Правила привязаны к конкретным классам-потребителям — при рефакторинге имён нужно обновлять.

✅ Рекомендуется

  • Использовать для инфраструктурных вариаций: разные хранилища/логгеры/очереди у разных модулей.
  • Задавать правила в composition root рядом с остальной сборкой.

❌ Антипаттерны

  • Строить бизнес-ветвление на contextual binding (это конфигурация инфраструктуры, а не управление логикой).
  • Плодить десятки правил вместо пересмотра границ модулей.

Аналоги в других контейнерах

Контейнер Аналог
PHP-DI через отдельные определения/фабрики (⚠️ менее прямо)
Symfony bind: по аргументам сервиса, #[Target]
Laravel when()->needs()->give() (тот же API)
Pimple нет (❌)
Nette разные сервисы + явная передача

CloudCastle, PHP-DI, Symfony, Laravel, Nette — CloudCastle и Laravel дают самый прямой fluent-API.

См. также: Contextual-binding (гайд) · bind().

Clone this wiki locally