public class EventProxy<T> where T : class
{
private readonly List<EventPublisher> subscriptions = new List<EventPublisher>();
public void Subscribe(string sourceEvent, T handler)
{
var handlerDelegate = handler as MulticastDelegate;
if (handlerDelegate == null)
return;
var evt = subscriptions.SingleOrDefault(k => k.Name == sourceEvent);
if (evt == null)
return;
evt.TargetHandlers.Add(new EventSubscriber() { Method = handlerDelegate.Method,
Instance = new WeakReference(handlerDelegate.Target)});
}
public T AttachPublisher(string publisherEvent)
{
var evt = subscriptions.SingleOrDefault(k => k.Name == publisherEvent);
if (evt == null)
{
evt = new EventPublisher() { Name = publisherEvent };
evt.Publisher = Delegate.CreateDelegate(typeof (T), evt, EventPublisher.Target, true) as T;
subscriptions.Add(evt);
}
return evt.Publisher;
}
private class EventPublisher
{
public static readonly MethodInfo Target = typeof(EventPublisher).GetMethod(
"HandleEvent",BindingFlags.Instance | BindingFlags.Public);
public string Name { get; set; }
public T Publisher { get; set; }
public List<EventSubscriber> TargetHandlers { get; private set; }
public EventPublisher()
{
TargetHandlers = new List<EventSubscriber>();
}
public void HandleEvent(object sender, object e)
{
TargetHandlers.RemoveAll(w => w.Instance.Target == null);
foreach (var reference in TargetHandlers)
{
var inst = reference.Instance.Target;
if (reference.Instance.IsAlive)
reference.Method.Invoke(inst, new[] {sender, e});
}
}
}
private class EventSubscriber
{
public WeakReference Instance { get; set; }
public MethodInfo Method { get; set; }
}
}