# 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.
