# 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 ```php // ❌ 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: ```php // ✅ 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 ```php // ✅ 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 ```php // ✅ 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 ```php // ✅ Richtig #[Initializer] public function __invoke(): SomeInterface { // Registriert Interface, das von anderen Initializern benötigt wird } ``` ### 2. Context-Filter nur für Setup-Initializer ```php // ✅ 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 ```php /** * 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: ```php // 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 - [Session Binding Initializer](session-binding-initializer.md) - [Dependency Injection](../features/dependency-injection.md) - [Initializer System](../features/initializer-system.md)