Skip to content

Feature Attribute autowiring

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

🏷️ Attribute autowiring

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

Разметка инъекции через PHP-атрибуты (#[Inject] и собственные). Декларативно указываете, что и как внедрять, прямо в коде класса.

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

Контейнер держит AttributeServiceIdRegistry — реестр атрибутов, помечающих точки инъекции. Встроенный #[Inject] работает «из коробки»; registerAttribute($attributeClass) добавляет свой атрибут. При autowiring инжекторы (PropertyInjector / MethodInjector) находят помеченные атрибутом члены и разрешают их зависимости (по типу или по явному id из атрибута).

use CloudCastle\DI\Attribute\Inject;

final class Mailer
{
    public function __construct(
        #[Inject(SmtpTransport::class)] private Transport $transport,
    ) {}
}

// свой атрибут-маркер:
#[Attribute(Attribute::TARGET_PARAMETER | Attribute::TARGET_PROPERTY)]
final class FromConfig {}

$c->registerAttribute(FromConfig::class);

Плюсы

  • Локальность: правило инъекции живёт рядом с зависимостью, а не в отдельном конфиге.
  • Свои атрибуты — можно выразить доменные правила (#[FromConfig], #[Tagged]).
  • Явный id в атрибуте снимает неоднозначность, когда типа недостаточно.

Минусы

  • Привязывает класс к атрибутам контейнера (небольшая связанность с инфраструктурой).
  • Разметка «размазана» по классам — общий обзор графа сложнее, чем в едином конфиге.

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

  • Использовать #[Inject(Id::class)] там, где по типу неоднозначно (несколько реализаций интерфейса).
  • Регистрировать доменные атрибуты через registerAttribute() для читаемых правил.

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

  • Дублировать атрибутами то, что и так решает constructor autowiring по типу, — лишний шум.
  • Прятать за атрибутами скалярную конфигурацию, которую честнее задать явно в фабрике/contextual.

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

Контейнер Аналог
PHP-DI #[Inject]; свои атрибуты — ограниченно (⚠️)
Symfony #[Autowire], #[Target], #[TaggedIterator]
Laravel атрибуты contextual (#[Give]) — частично
Pimple нет (❌)
Nette @inject / атрибуты

CloudCastle, Symfony, Laravel, Nette — включая пользовательские inject-атрибуты (CloudCastle — полноценно).

См. также: Property и method injection · Contextual binding.

Clone this wiki locally