Files
michaelschiemer/docs/claude/initializer-context-filtering.md
2025-11-24 21:28:25 +01:00

4.9 KiB

Initializer Context Filtering

Übersicht

Initializer können mit ContextType-Filtern versehen werden, um zu steuern, in welchen Execution-Contexts sie ausgeführt werden sollen. Dies ist jedoch mit Vorsicht zu verwenden, da die Discovery während der Bootstrap-Phase läuft.

Problem: Context-Filter während Bootstrap

Wichtig: Die Discovery scannt und verarbeitet Initializer während der Bootstrap-Phase, wenn der Execution-Context noch cli-script ist (nicht web).

Beispiel-Problem

// ❌ Problem: Wird während Bootstrap übersprungen
#[Initializer(ContextType::WEB)]
public function __invoke(): SomeInterface
{
    // ...
}

Warum: Die Discovery läuft während der Bootstrap-Phase im cli-script Context. Initializer mit ContextType::WEB Filter werden deshalb übersprungen (shouldSkipInitializer() gibt true zurück).

Lösung: Kein Context-Filter für Dependency-Registrierung

Initializer, die Dependencies registrieren müssen, sollten keinen ContextType-Filter haben:

// ✅ Richtig: Wird während Bootstrap gefunden und ausgeführt
#[Initializer]
public function __invoke(): SomeInterface
{
    // ...
}

Wann Context-Filter verwenden?

Geeignet für Context-Filter

  • Setup-Initializer (void-Return), die nur in bestimmten Contexts ausgeführt werden sollen
  • Initializer, die nur für bestimmte Contexts benötigt werden und keine Dependencies für andere Initializer bereitstellen

Nicht geeignet für Context-Filter

  • Initializer, die Interfaces oder Services registrieren, die von anderen Initializern benötigt werden
  • Initializer, die während der Bootstrap-Phase verfügbar sein müssen

Beispiel: SessionBindingInitializer

// ✅ Kein Context-Filter: Muss während Bootstrap verfügbar sein
#[Initializer]
public function __invoke(): void
{
    // Registriert SessionInterface als lazy binding
    // Wird von ActionAuthorizationCheckerInitializer benötigt
}

Grund: SessionBindingInitializer registriert SessionInterface, das von ActionAuthorizationCheckerInitializer benötigt wird. Wenn SessionBindingInitializer einen ContextType::WEB Filter hätte, würde er während der Bootstrap-Phase übersprungen werden, und ActionAuthorizationCheckerInitializer würde fehlschlagen.

Beispiel: ActionAuthorizationCheckerInitializer

// ✅ Kein Context-Filter: Muss während Bootstrap verfügbar sein
#[Initializer]
public function __invoke(): ActionAuthorizationChecker
{
    // Benötigt SessionInterface (von SessionBindingInitializer)
    // Muss während Bootstrap verfügbar sein, auch wenn nur für WEB verwendet
}

Grund: Obwohl ActionAuthorizationChecker nur für WEB-Requests verwendet wird, muss der Initializer während der Bootstrap-Phase verfügbar sein, damit die Dependency-Injection funktioniert.

Discovery-Prozess

  1. Bootstrap-Phase: Discovery scannt alle Initializer
  2. Context-Filter-Prüfung: shouldSkipInitializer() prüft, ob Initializer für aktuellen Context erlaubt ist
  3. Überspringen: Initializer mit nicht-passendem Context werden übersprungen
  4. Registrierung: Verbleibende Initializer werden registriert

Best Practices

1. Kein Context-Filter für Dependency-Registrierung

// ✅ Richtig
#[Initializer]
public function __invoke(): SomeInterface
{
    // Registriert Interface, das von anderen Initializern benötigt wird
}

2. Context-Filter nur für Setup-Initializer

// ✅ Geeignet: Setup-Initializer mit Context-Filter
#[Initializer(ContextType::WEB)]
public function __invoke(): void
{
    // Setup-Code, der nur für WEB-Contexts benötigt wird
    // Wird nicht von anderen Initializern benötigt
}

3. Dokumentation hinzufügen

/**
 * No ContextType filter: This initializer must be available during bootstrap
 * (even if context is cli-script) so it can be registered in the container.
 * The actual session will be provided by SessionMiddleware when processing web requests.
 */
#[Initializer]
public function __invoke(): SomeInterface
{
    // ...
}

Troubleshooting

Problem: Initializer wird nicht gefunden

Symptom: "No initializers found that return this interface"

Ursache: Initializer hat ContextType-Filter, der während Bootstrap nicht passt

Lösung: Entferne den ContextType-Filter:

// Vorher
#[Initializer(ContextType::WEB)]

// Nachher
#[Initializer]

Problem: Dependency-Injection-Fehler

Symptom: "Cannot resolve parameter 'session' for method..."

Ursache: Initializer, der Dependency bereitstellt, hat ContextType-Filter

Lösung: Entferne den ContextType-Filter vom Dependency-Provider-Initializer

Siehe auch