- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
201 lines
4.8 KiB
Markdown
201 lines
4.8 KiB
Markdown
# 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.
|