Event Bus et le pattern Observer en C# (.NET) : implémentation et exemples

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Event Bus et le pattern Observer en C# (.NET) : de la théorie à la pratique



Dans le développement moderne en C# (.NET), l'un des principes clés est le couplage faible (loose coupling) entre les composants du système. Le pattern Observer (Observateur) et son évolution — l'Event Bus (Bus d'événements) — offrent un mécanisme élégant pour organiser l'interaction entre objets sans dépendances directes. Dans cet article, nous analyserons en détail comment implémenter un Event Bus en C# (.NET), examinerons son architecture et fournirons des exemples pratiques.



Qu'est-ce que le pattern Observer ?

Le pattern Observer définit une relation « un à plusieurs » entre objets : lorsqu'un objet (le sujet) modifie son état, tous les objets qui en dépendent (les observateurs) sont automatiquement notifiés et mis à jour. En C#, ce pattern est traditionnellement implémenté via les événements (event) et les délégués.



Problème de l'implémentation classique

Bien que les événements intégrés de C# fonctionnent bien, ils présentent des limitations :

  • Lien direct : l'éditeur doit connaître explicitement les abonnés.
  • Complexité du désabonnement : si un abonné oublie de se désabonner, cela provoque une fuite mémoire.
  • Flexibilité limitée : il est difficile d'organiser un traitement asynchrone ou un filtrage des événements.


Qu'est-ce qu'un Event Bus ?

Un Event Bus est un bus centralisé (médiateur) qui implémente le pattern Publisher-Subscriber (Éditeur-Abonné). Contrairement à l'Observer classique, l'éditeur et l'abonné ne se connaissent pas du tout. Ils communiquent uniquement via le bus :

  • L'éditeur envoie un message (événement) dans le bus.
  • Le bus trouve tous les abonnés à ce type d'événement et les notifie.
  • L'abonné s'enregistre pour un type d'événement spécifique et le traite.


Avantages de l'Event Bus

  • Couplage faible : les composants ne dépendent pas les uns des autres.
  • Évolutivité : il est facile d'ajouter de nouveaux abonnés.
  • Testabilité : on peut remplacer le bus par des mocks.
  • Asynchronisme : on peut traiter les événements dans des threads d'arrière-plan.


Implémentation d'un Event Bus en C# (.NET)

Examinons une implémentation simple mais fonctionnelle. Créons une classe EventBus qui stockera un dictionnaire d'abonnés.



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); }

Recommendations