Enable Discovery debug logging for production troubleshooting
- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
This commit is contained in:
@@ -0,0 +1,200 @@
|
||||
# Erweiterungsmuster im Framework
|
||||
|
||||
## Übersicht
|
||||
|
||||
Dieses Dokument beschreibt die verschiedenen Muster und Techniken, um das Framework zu erweitern oder anzupassen, ohne den Kern-Code zu verändern.
|
||||
|
||||
## Event-basierte Erweiterungen
|
||||
|
||||
### Event-Listener
|
||||
|
||||
Die primäre Methode zur Erweiterung des Frameworks ist das Lauschen auf System-Events:
|
||||
|
||||
```php
|
||||
// Event-Listener registrieren
|
||||
public function __construct(private readonly EventDispatcher $eventDispatcher)
|
||||
{
|
||||
$this->eventDispatcher->addHandler(
|
||||
'App\Framework\Core\Events\ApplicationBooted',
|
||||
[$this, 'onApplicationBooted']
|
||||
);
|
||||
}
|
||||
|
||||
// Event-Handler-Methode
|
||||
public function onApplicationBooted(ApplicationBooted $event): void
|
||||
{
|
||||
// Erweiterungslogik implementieren
|
||||
}
|
||||
```
|
||||
|
||||
### Eigene Events
|
||||
|
||||
Benutzerdefinierte Events erstellen:
|
||||
|
||||
```php
|
||||
final readonly class UserRegistered
|
||||
{
|
||||
public function __construct(
|
||||
public string $userId,
|
||||
public string $email,
|
||||
public \DateTimeImmutable $timestamp
|
||||
) {}
|
||||
}
|
||||
|
||||
// Event auslösen
|
||||
$this->eventDispatcher->dispatch(new UserRegistered(
|
||||
$user->getId(),
|
||||
$user->getEmail(),
|
||||
new \DateTimeImmutable()
|
||||
));
|
||||
```
|
||||
|
||||
## Middleware
|
||||
|
||||
HTTP-Anfragen können durch Middleware-Klassen erweitert werden:
|
||||
|
||||
```php
|
||||
final readonly class CustomMiddleware implements Middleware
|
||||
{
|
||||
public function process(Request $request, callable $next): Response
|
||||
{
|
||||
// Vor der Anfrageverarbeitung
|
||||
$modifiedRequest = $this->modifyRequest($request);
|
||||
|
||||
// Anfrage weiterleiten
|
||||
$response = $next($modifiedRequest);
|
||||
|
||||
// Nach der Anfrageverarbeitung
|
||||
return $this->modifyResponse($response);
|
||||
}
|
||||
}
|
||||
|
||||
// Middleware registrieren
|
||||
$app->addMiddleware(CustomMiddleware::class);
|
||||
```
|
||||
|
||||
## Service-Erweiterungen
|
||||
|
||||
### Service-Ersetzen
|
||||
|
||||
Standardimplementierungen durch eigene ersetzen:
|
||||
|
||||
```php
|
||||
#[Initializer]
|
||||
final readonly class CustomStorageInitializer
|
||||
{
|
||||
public function __invoke(Container $container): StorageInterface
|
||||
{
|
||||
return new CustomStorage();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Service-Decorator
|
||||
|
||||
Bestehende Services erweitern ohne Änderung der Original-Implementierung:
|
||||
|
||||
```php
|
||||
#[Initializer]
|
||||
final readonly class LoggingAnalyticsInitializer
|
||||
{
|
||||
public function __construct(
|
||||
private readonly Configuration $config,
|
||||
private readonly LoggerInterface $logger
|
||||
) {}
|
||||
|
||||
public function __invoke(Container $container): Analytics
|
||||
{
|
||||
// Original-Analytics-Service erstellen
|
||||
$originalAnalytics = new Analytics(
|
||||
new AnalyticsManager($this->config->get('analytics'), new FileStorage($path)),
|
||||
$container->get(EventDispatcher::class)
|
||||
);
|
||||
|
||||
// Mit Logging-Decorator umhüllen
|
||||
return new LoggingAnalyticsDecorator($originalAnalytics, $this->logger);
|
||||
}
|
||||
}
|
||||
|
||||
// Decorator-Implementierung
|
||||
final readonly class LoggingAnalyticsDecorator implements AnalyticsInterface
|
||||
{
|
||||
public function __construct(
|
||||
private Analytics $analytics,
|
||||
private LoggerInterface $logger
|
||||
) {}
|
||||
|
||||
public function track(string $event, array $properties = [], ?string $userId = null): void
|
||||
{
|
||||
$this->logger->debug("Tracking event: {$event}", [
|
||||
'properties' => $properties,
|
||||
'user_id' => $userId
|
||||
]);
|
||||
|
||||
$this->analytics->track($event, $properties, $userId);
|
||||
}
|
||||
|
||||
// Andere Methoden implementieren
|
||||
}
|
||||
```
|
||||
|
||||
## Plugin-System
|
||||
|
||||
### Plugin-Interface
|
||||
|
||||
```php
|
||||
interface PluginInterface
|
||||
{
|
||||
public function register(Application $app): void;
|
||||
public function boot(Application $app): void;
|
||||
}
|
||||
|
||||
// Plugin-Implementierung
|
||||
final readonly class CustomPlugin implements PluginInterface
|
||||
{
|
||||
public function register(Application $app): void
|
||||
{
|
||||
// Services registrieren
|
||||
}
|
||||
|
||||
public function boot(Application $app): void
|
||||
{
|
||||
// Nach Initialisierung der Anwendung
|
||||
}
|
||||
}
|
||||
|
||||
// Plugin registrieren
|
||||
$app->registerPlugin(new CustomPlugin());
|
||||
```
|
||||
|
||||
## Konfigurationserweiterungen
|
||||
|
||||
### Konfigurationsquellen
|
||||
|
||||
Benutzerdefinierte Konfigurationsquellen implementieren:
|
||||
|
||||
```php
|
||||
final readonly class EnvironmentConfigSource implements ConfigSourceInterface
|
||||
{
|
||||
public function load(string $key, mixed $default = null): mixed
|
||||
{
|
||||
$envKey = strtoupper(str_replace('.', '_', $key));
|
||||
return $_ENV[$envKey] ?? $default;
|
||||
}
|
||||
}
|
||||
|
||||
// Konfigurationsquelle registrieren
|
||||
$config->addSource(new EnvironmentConfigSource());
|
||||
```
|
||||
|
||||
## Zusammenfassung
|
||||
|
||||
Die bevorzugten Erweiterungsmuster sind:
|
||||
|
||||
1. **Event-Listener** für reaktive Erweiterungen
|
||||
2. **Middleware** für HTTP-Anfrageverarbeitung
|
||||
3. **Service-Initializer** zum Ersetzen oder Dekorieren von Services
|
||||
4. **Plugins** für umfassendere Funktionalitätserweiterungen
|
||||
5. **Konfigurationsquellen** für benutzerdefinierte Konfigurationen
|
||||
|
||||
Diese Muster ermöglichen es, das Framework zu erweitern, ohne den Kern zu modifizieren, was zu einer besseren Wartbarkeit und einfacheren Updates führt.
|
||||
Reference in New Issue
Block a user