fix: DockerSecretsResolver - don't normalize absolute paths like /var/www/html/...
Some checks failed
Deploy Application / deploy (push) Has been cancelled
Some checks failed
Deploy Application / deploy (push) Has been cancelled
This commit is contained in:
129
docs/claude/session-binding-initializer.md
Normal file
129
docs/claude/session-binding-initializer.md
Normal file
@@ -0,0 +1,129 @@
|
||||
# Session Binding Initializer
|
||||
|
||||
## Übersicht
|
||||
|
||||
Der `SessionBindingInitializer` löst das Problem, dass `SessionInterface` während der Bootstrap-Phase noch nicht verfügbar ist, wenn Initializer ausgeführt werden, die `SessionInterface` als Dependency benötigen.
|
||||
|
||||
## Problem
|
||||
|
||||
**Timing-Problem**: `SessionInterface` wird normalerweise von `SessionMiddleware` während der Request-Verarbeitung gebunden. Initializer laufen jedoch während der Bootstrap-Phase, bevor ein Request verarbeitet wird. Dies führt zu Dependency-Injection-Fehlern, wenn Initializer `SessionInterface` als Dependency benötigen.
|
||||
|
||||
**Beispiel**: `ActionAuthorizationCheckerInitializer` benötigt `SessionInterface`, um `SessionBasedAuthorizationChecker` zu erstellen. Ohne `SessionBindingInitializer` würde die Dependency-Injection fehlschlagen.
|
||||
|
||||
## Lösung
|
||||
|
||||
Der `SessionBindingInitializer` registriert `SessionInterface` als **lazy binding** im Container:
|
||||
|
||||
```php
|
||||
#[Initializer]
|
||||
public function __invoke(): void
|
||||
{
|
||||
$sessionManager = $this->sessionManager;
|
||||
$this->container->singleton(SessionInterface::class, function(Container $c) use ($sessionManager) {
|
||||
// Check if Session is already bound (by Middleware)
|
||||
if ($c->has(Session::class)) {
|
||||
return $c->get(Session::class);
|
||||
}
|
||||
|
||||
// Fallback: Create new session without request context
|
||||
// This will be overridden by SessionMiddleware when request is available
|
||||
return $sessionManager->createNewSession();
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
## Funktionsweise
|
||||
|
||||
1. **Lazy Binding**: `SessionInterface` wird als Closure registriert, die erst ausgeführt wird, wenn `SessionInterface` tatsächlich benötigt wird.
|
||||
|
||||
2. **Fallback-Mechanismus**:
|
||||
- Wenn `SessionMiddleware` bereits gelaufen ist, wird die bereits gebundene `Session` verwendet.
|
||||
- Andernfalls wird eine neue Session ohne Request-Context erstellt.
|
||||
|
||||
3. **Override durch Middleware**: `SessionMiddleware` überschreibt das lazy binding mit der tatsächlichen Session-Instanz, wenn ein Request verarbeitet wird.
|
||||
|
||||
## Verwendung
|
||||
|
||||
Initializer, die `SessionInterface` benötigen, können es einfach als Dependency injizieren:
|
||||
|
||||
```php
|
||||
final readonly class ActionAuthorizationCheckerInitializer
|
||||
{
|
||||
public function __construct(
|
||||
private Container $container
|
||||
) {
|
||||
}
|
||||
|
||||
#[Initializer]
|
||||
public function __invoke(): ActionAuthorizationChecker
|
||||
{
|
||||
// SessionInterface wird automatisch vom lazy binding bereitgestellt
|
||||
$session = $this->container->get(SessionInterface::class);
|
||||
|
||||
$checker = new SessionBasedAuthorizationChecker($session);
|
||||
$this->container->singleton(ActionAuthorizationChecker::class, $checker);
|
||||
|
||||
return $checker;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Wichtige Hinweise
|
||||
|
||||
### Kein ContextType-Filter
|
||||
|
||||
**Wichtig**: Der `SessionBindingInitializer` hat **keinen** `ContextType`-Filter:
|
||||
|
||||
```php
|
||||
#[Initializer] // ✅ Kein ContextType::WEB Filter
|
||||
public function __invoke(): void
|
||||
```
|
||||
|
||||
**Grund**: Die Discovery läuft während der Bootstrap-Phase, wenn der Context noch `cli-script` ist. Ein `ContextType::WEB` Filter würde dazu führen, dass der Initializer übersprungen wird und `SessionInterface` nicht registriert wird.
|
||||
|
||||
### Discovery-Timing
|
||||
|
||||
Die Discovery scannt Initializer während der Bootstrap-Phase, bevor Requests verarbeitet werden. Initializer mit ContextType-Filtern werden nur ausgeführt, wenn der aktuelle Context passt. Da die Bootstrap-Phase im `cli-script` Context läuft, werden Initializer mit `ContextType::WEB` Filter übersprungen.
|
||||
|
||||
**Lösung**: Initializer, die für die Dependency-Registrierung benötigt werden, sollten **keinen** ContextType-Filter haben, auch wenn sie nur für WEB-Contexts verwendet werden.
|
||||
|
||||
## Dateien
|
||||
|
||||
- **Initializer**: `src/Framework/Http/Session/SessionBindingInitializer.php`
|
||||
- **Verwendet von**: `src/Framework/LiveComponents/Security/ActionAuthorizationCheckerInitializer.php`
|
||||
- **Middleware**: `src/Framework/Http/Session/SessionMiddleware.php`
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Problem: "Cannot instantiate interface SessionInterface"
|
||||
|
||||
**Ursache**: `SessionBindingInitializer` wurde nicht gefunden oder nicht ausgeführt.
|
||||
|
||||
**Lösung**:
|
||||
1. Prüfe, ob `SessionBindingInitializer` das `#[Initializer]` Attribut hat (ohne ContextType-Filter).
|
||||
2. Leere den Discovery-Cache: `php console.php discovery:clear-cache`
|
||||
3. Prüfe die Logs, ob der Initializer gefunden wurde.
|
||||
|
||||
### Problem: Initializer wird nicht gefunden
|
||||
|
||||
**Ursache**: ContextType-Filter verhindert, dass der Initializer während der Bootstrap-Phase gefunden wird.
|
||||
|
||||
**Lösung**: Entferne den `ContextType`-Filter vom `#[Initializer]` Attribut:
|
||||
|
||||
```php
|
||||
// ❌ Falsch: Wird während Bootstrap übersprungen
|
||||
#[Initializer(ContextType::WEB)]
|
||||
|
||||
// ✅ Richtig: Wird während Bootstrap gefunden
|
||||
#[Initializer]
|
||||
```
|
||||
|
||||
## Siehe auch
|
||||
|
||||
- [Dependency Injection](../features/dependency-injection.md)
|
||||
- [Session Management](../features/session-management.md)
|
||||
- [Initializer System](../features/initializer-system.md)
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user