Skip to content

Instantly share code, notes, and snippets.

@audinue
Last active July 24, 2017 00:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save audinue/e39bca3456950829406cbf47a06ddbbf to your computer and use it in GitHub Desktop.
Save audinue/e39bca3456950829406cbf47a06ddbbf to your computer and use it in GitHub Desktop.
C# Hub

C# Hub

Usage:

var hub = new Hub();

hub.On((YourMessage message) => {
  // do stuff
});

// or

hub.On<YourMessage>(message => {
  // do stuff
});

hub.Notify(new YourMessage());

Available methods are On, Once, Off, Notify and Dispose.

The Hub class meant to be used while Hub<T> class meant to be inherited.

using System;
using System.Collections.Generic;
public abstract class Hub<T> : IDisposable where T : Hub<T>
{
private Dictionary<Type, List<MulticastDelegate>> subscribers = new Dictionary<Type, List<MulticastDelegate>>();
private bool disposed;
private void CheckDisposed()
{
if (disposed)
{
throw new ObjectDisposedException(GetType().FullName);
}
}
public T On<M>(Action<M> action)
{
CheckDisposed();
var type = typeof(M);
if (!subscribers.ContainsKey(type))
{
subscribers[type] = new List<MulticastDelegate>();
}
subscribers[type].Add(action);
return (T)this;
}
public T Once<M>(Action<M> action)
{
CheckDisposed();
Action<M> proxy = null;
proxy = message =>
{
action(message);
Off(proxy);
};
return this.On(proxy);
}
public T Off<M>(Action<M> action)
{
CheckDisposed();
var type = typeof(M);
if (subscribers.ContainsKey(type))
{
subscribers[type].Remove(action);
}
return (T)this;
}
public T Notify<M>(M message)
{
CheckDisposed();
var type = typeof(M);
if (subscribers.ContainsKey(type))
{
foreach (var action in subscribers[type].ToArray())
{
action.DynamicInvoke(message);
}
}
return (T)this;
}
public virtual void Dispose()
{
if (!disposed)
{
subscribers = null;
disposed = true;
}
}
}
public sealed class Hub : Hub<Hub>
{
}
using System;
class HubTest
{
class HelloWorldMessage
{
}
static void Main(string[] args)
{
var hub = new Hub();
var notified = 0;
var action = new Action<HelloWorldMessage>(message =>
{
notified++;
});
hub.On(action);
hub.Notify(new HelloWorldMessage());
if (notified != 1)
{
throw new Exception();
}
hub.Off(action);
if (notified != 1)
{
throw new Exception();
}
hub.Once(action);
hub.Notify(new HelloWorldMessage());
if (notified != 2)
{
throw new Exception();
}
hub.Notify(new HelloWorldMessage());
if (notified != 2)
{
throw new Exception();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment