Skip to content

Instantly share code, notes, and snippets.

@AtomicBlom
Created October 30, 2017 05:53
Show Gist options
  • Save AtomicBlom/1d8742caf330889996da3c38e7850781 to your computer and use it in GitHub Desktop.
Save AtomicBlom/1d8742caf330889996da3c38e7850781 to your computer and use it in GitHub Desktop.
Reactive.EventAggregator adapter for Template10
using System;
using System.Collections.Generic;
using System.Linq;
using Reactive.EventAggregator;
using Template10.Services.Messenger;
namespace Sample.Framework.Messaging.RxEventAggregator
{
public class RxEventAggregatorMessagingAdapter : IMessengerAdapter
{
private readonly IEventAggregator _eventAggregator;
public RxEventAggregatorMessagingAdapter(IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator;
}
public void Send<T>(T message)
{
//The only thing I actually needed
_eventAggregator.Publish(message);
//Code from here down is because it's quite difficult to manage IDisposable objects without causing memory leaks
if (_subscriptions.TryGetValue(typeof(T), out var subscripedList))
{
foreach (var objectAndAction in subscripedList.ToArray())
{
objectAndAction.Invoke(message);
}
}
}
private readonly Dictionary<Type, List<IObjectAndAction>> _subscriptions = new Dictionary<Type, List<IObjectAndAction>>();
public void Subscribe<T>(object subscriber, Action<T> callback)
{
var key = new ObjectAndAction<T>
{
Action = callback,
Object = subscriber,
Type = typeof(T)
};
if (!_subscriptions.TryGetValue(key.Type, out var subscribers))
{
subscribers = new List<IObjectAndAction>();
_subscriptions.Add(key.Type, subscribers);
}
subscribers.Add(key);
}
public void Unsubscribe<T>(object subscriber, Action<T> callback)
{
var objectAndActions = _subscriptions.Values.SelectMany(x => x).Where(s => s.AreEqual(subscriber, callback)).ToArray();
foreach (var objectAndAction in objectAndActions)
{
if (_subscriptions.TryGetValue(objectAndAction.Type, out var subscripedList))
{
subscripedList.Remove(objectAndAction);
}
}
}
public void Unsubscribe(object subscriber)
{
var objectAndActions = _subscriptions.Values.SelectMany(x => x).Where(s => s.Object == subscriber).ToArray();
foreach (var objectAndAction in objectAndActions)
{
if (_subscriptions.TryGetValue(objectAndAction.Type, out var subscripedList))
{
subscripedList.Remove(objectAndAction);
}
}
}
private interface IObjectAndAction
{
void Invoke(object message);
object Object { get; }
Type Type { get; }
bool AreEqual<T>(object subscriber, Action<T> action);
}
private class ObjectAndAction<T> : IObjectAndAction
{
public object Object { get; set; }
public Action<T> Action { private get; set; }
public Type Type { get; set; }
public bool AreEqual<TOtherAction>(object subscriber, Action<TOtherAction> action)
{
return Equals(subscriber, Object) && Equals(action, Action);
}
public void Invoke(object message)
{
Action((T)message);
}
}
}
}
using Template10.Services.Messenger;
namespace Sample.Framework.Messaging.RxEventAggregator
{
public class RxEventAggregatorMessengerService : MessengerService
{
public RxEventAggregatorMessengerService(IMessengerAdapter adapter)
: base(adapter)
{
// empty
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment