Event Bus und das Observer-Pattern in C# (.NET): Implementierung und Beispiele

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Event Bus und das Observer-Pattern in C# (.NET): Von der Theorie zur Praxis



In der modernen Entwicklung mit C# (.NET) ist eines der Schlüsselprinzipien die lose Kopplung (loose coupling) zwischen den Komponenten des Systems. Das Observer-Pattern (Beobachter) und seine Weiterentwicklung — der Event Bus (Ereignisbus) — bieten einen eleganten Mechanismus zur Organisation der Interaktion zwischen Objekten ohne direkte Abhängigkeiten. In diesem Artikel werden wir detailliert erläutern, wie man einen Event Bus in C# (.NET) implementiert, seine Architektur betrachten und praktische Beispiele geben.



Was ist das Observer-Pattern?

Das Observer-Pattern definiert eine „Eins-zu-Viele“-Beziehung zwischen Objekten: Wenn ein Objekt (Subjekt) seinen Zustand ändert, werden alle abhängigen Objekte (Beobachter) automatisch benachrichtigt und aktualisiert. In C# wird dieses Pattern traditionell über Ereignisse (event) und Delegaten implementiert.



Problem der klassischen Implementierung

Obwohl die integrierten C#-Ereignisse gut funktionieren, haben sie Einschränkungen:

  • Direkte Verbindung: Der Herausgeber muss die Abonnenten explizit kennen.
  • Komplexität der Abmeldung: Wenn ein Abonnent vergisst, sich abzumelden, entsteht ein Speicherleck.
  • Eingeschränkte Flexibilität: Asynchrone Verarbeitung oder Filterung von Ereignissen sind schwer zu organisieren.


Was ist ein Event Bus?

Event Bus ist ein zentraler Bus (Vermittler), der das Publisher-Subscriber-Pattern (Herausgeber-Abonnent) implementiert. Im Gegensatz zum klassischen Observer kennen sich Herausgeber und Abonnent überhaupt nicht. Sie kommunizieren nur über den Bus:

  • Herausgeber sendet eine Nachricht (Ereignis) an den Bus.
  • Bus findet alle Abonnenten für diesen Ereignistyp und benachrichtigt sie.
  • Abonnent registriert sich für einen bestimmten Ereignistyp und verarbeitet ihn.


Vorteile des Event Bus

  • Lose Kopplung: Komponenten sind nicht voneinander abhängig.
  • Skalierbarkeit: Neue Abonnenten können leicht hinzugefügt werden.
  • Testbarkeit: Der Bus kann durch Mocks ersetzt werden.
  • Asynchronität: Ereignisse können in Hintergrundthreads verarbeitet werden.


Implementierung eines Event Bus in C# (.NET)

Betrachten wir eine einfache, aber funktionale Implementierung. Wir erstellen eine Klasse EventBus, die ein Wörterbuch der Abonnenten speichert.



public interface IEventBus{    void Publish<TEvent>(TEvent eventData) where TEvent : class;    IDisposable Subscribe<TEvent>(Action<TEvent> handler) where TEvent : class;}

public class EventBus : IEventBus{ private readonly Dictionary<Type, List<Delegate>> _subscribers = new(); private readonly object _lock = new();

public void Publish<TEvent>(TEvent eventData) where TEvent : class { List<Delegate> handlers; lock (_lock) { if (!_subscribers.TryGetValue(typeof(TEvent), out var list)) return; handlers = new List<Delegate>(list); }

foreach (var handler in handlers) { if (handler is Action<TEvent> action) action(eventData); } }

public IDisposable Subscribe<TEvent>(Action<TEvent> handler) where TEvent : class { lock (_lock) { if (!_subscribers.ContainsKey(typeof(TEvent))) _subscribers[typeof(TEvent)] = new List<Delegate>(); _subscribers[typeof(TEvent)].Add(handler); }

return new Unsubscriber(() => { lock (_lock) { if (_subscribers.TryGetValue(typeof(TEvent), out var list)) list.Remove(handler); }

Empfehlungen