Last active
July 16, 2021 12:10
-
-
Save noseratio/d25371c91656e2d1c05e97700cc0fd98 to your computer and use it in GitHub Desktop.
Simple pub/sub event hub implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#nullable enable | |
using System; | |
namespace conapp | |
{ | |
/// <summary> | |
/// Resembling JavaScript's EventTarget | |
/// </summary> | |
public class EventTarget<T> where T : EventArgs | |
{ | |
public event EventHandler<T>? Event; | |
public void Dispatch(object? source, T eventArgs) => | |
this.Event?.Invoke(source, eventArgs); | |
} | |
/// <summary> | |
/// Emdbedding EventTarget into a container class as a property | |
/// </summary> | |
public interface IEventTargetProp<T> where T : EventArgs | |
{ | |
public EventTarget<T> Value { get; init; } | |
} | |
/// <summary> | |
/// Implemented by EventTarget container class | |
/// </summary> | |
public interface IEventTargetHub | |
{ | |
public EventTarget<T>? GetEventTarget<T>() | |
where T : EventArgs => | |
(this as IEventTargetProp<T>)?.Value; | |
} | |
/// <summary> | |
/// Access EventTarget events on a container class using IEventTargetHub | |
/// </summary> | |
public static class EventTargetHubExtensions | |
{ | |
public static bool HasEventTarget<T>(this IEventTargetHub @this) | |
where T : EventArgs => | |
@this.GetEventTarget<T>() != null; | |
public static void AddListener<T>(this IEventTargetHub @this, EventHandler<T> listener) | |
where T : EventArgs => | |
@this.GetEventTarget<T>()!.Event += listener; | |
public static void RemoveListener<T>(this IEventTargetHub @this, EventHandler<T> listener) | |
where T : EventArgs => | |
@this.GetEventTarget<T>()!.Event -= listener; | |
public static void Dispatch<T>(this IEventTargetHub @this, object? source, T eventArgs) | |
where T : EventArgs => | |
@this.GetEventTarget<T>()?.Dispatch(source, eventArgs); | |
} | |
// define some event signatures | |
class MyEventArgs : EventArgs { } | |
class YourEventArgs : EventArgs { } | |
class TheirEventArgs : EventArgs { } | |
// event container (hub) | |
class EventHub : | |
IEventTargetHub, | |
IEventTargetProp<MyEventArgs>, | |
IEventTargetProp<YourEventArgs>, | |
IEventTargetProp<TheirEventArgs> | |
{ | |
EventTarget<MyEventArgs> IEventTargetProp<MyEventArgs>.Value { get; init; } = new(); | |
EventTarget<YourEventArgs> IEventTargetProp<YourEventArgs>.Value { get; init; } = new(); | |
EventTarget<TheirEventArgs> IEventTargetProp<TheirEventArgs>.Value { get; init; } = new(); | |
} | |
// event listener | |
class Listener | |
{ | |
public Listener(IEventTargetHub hub) | |
{ | |
hub.GetEventTarget<MyEventArgs>()!.Event += Listener_Event; | |
hub.GetEventTarget<YourEventArgs>()!.Event += Listener_Event; | |
hub.GetEventTarget<TheirEventArgs>()!.Event += Listener_Event; | |
} | |
private void Listener_Event(object? sender, EventArgs e) => | |
Console.WriteLine($"Listened to: {e.GetType().Name}"); | |
} | |
// dispatch some events | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
var hub = new EventHub(); | |
var listener = new Listener(hub); | |
hub.Dispatch(hub, new MyEventArgs()); | |
hub.Dispatch(hub, new YourEventArgs()); | |
hub.Dispatch(hub, new TheirEventArgs()); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment