using System.Collections.Generic;
using System.Collections.ObjectModel;
public static void Main()
var messenger = new Messenger();
var receiver = new Receiver(messenger);
var sender = new Sender(messenger);
public Receiver(Messenger messenger)
messenger.Register<string>(x =>
messenger.Register<string, string>(x =>
messenger.Register<string, string>(x =>
public Sender(Messenger messenger)
messenger.Send<string>("Hello world!");
foreach (string result in messenger.Request<string, string>("hello"))
Console.WriteLine(result);
foreach (string result in messenger.Request<string, string>("world"))
Console.WriteLine(result);
private Dictionary<Type, Delegate> actions = new Dictionary<Type, Delegate>();
private Dictionary<Type, Collection<Delegate>> functions = new Dictionary<Type, Collection<Delegate>>();
public void Register<T, R>(Func<T, R> request)
throw new ArgumentNullException("request");
if (functions.ContainsKey(typeof(T)))
functions[typeof(T)].Add(request);
functions.Add(typeof(T), new Collection<Delegate>()
public void Register<T>(Action<T> action)
throw new ArgumentNullException("action");
if (actions.ContainsKey(typeof(T)))
actions[typeof(T)] = Delegate.Combine(actions[typeof(T)], action);
actions.Add(typeof(T), action);
public IEnumerable<R> Request<T, R>(T parameter)
if (functions.ContainsKey(typeof(T)))
var applicableFunctions = functions[typeof(T)].OfType<Func<T, R>>();
foreach (var function in applicableFunctions)
yield return function(parameter);
public void Send<T>(T message)
if (actions.ContainsKey(typeof(T)))
((Action<T>)actions[typeof(T)])(message);
public void Unregister<T, R>(Func<T, R> request)
if (functions.ContainsKey(typeof(T)) && functions[typeof(T)].Contains(request))
functions[typeof(T)].Remove(request);
public void Unregister<T>(Action<T> action)
if (actions.ContainsKey(typeof(T)))
actions[typeof(T)] = (Action<T>)Delegate.Remove(actions[typeof(T)], action);