Commit d7fe04b
Changed files (2)
trunk
product
MyMoney
Infrastructure
trunk/product/MyMoney/Infrastructure/eventing/EventAggregator.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Linq;
using System.Threading;
using MoMoney.Utility.Extensions;
@@ -9,23 +8,23 @@ namespace MoMoney.Infrastructure.eventing
public interface IEventAggregator
{
void subscribe_to<Event>(IEventSubscriber<Event> subscriber) where Event : IEvent;
- void subscribe(object subscriber);
+ void subscribe<Listener>(Listener subscriber) where Listener : class;
void publish<Event>(Event the_event_to_broadcast) where Event : IEvent;
+ void publish<T>(Action<T> call) where T : class;
void publish<Event>() where Event : IEvent, new();
}
public class EventAggregator : IEventAggregator
{
- //readonly IDictionary<string, List<object>> subscribers;
readonly SynchronizationContext context;
- readonly HashSet<object> listeners;
+ readonly HashSet<object> subscribers;
readonly object mutex;
- public EventAggregator()
+ public EventAggregator(SynchronizationContext context)
{
- //subscribers = new Dictionary<string, List<object>>();
- listeners = new HashSet<object>();
+ subscribers = new HashSet<object>();
mutex = new object();
+ this.context = context;
}
public void subscribe_to<Event>(IEventSubscriber<Event> subscriber) where Event : IEvent
@@ -33,18 +32,19 @@ namespace MoMoney.Infrastructure.eventing
subscribe(subscriber);
}
- public void subscribe(object subscriber)
+ public void subscribe<Listener>(Listener subscriber) where Listener : class
{
- within_lock(() => listeners.Add(subscriber));
+ within_lock(() => subscribers.Add(subscriber));
}
public void publish<Event>(Event the_event_to_broadcast) where Event : IEvent
{
- //get_list_for<Event>()
- // .Select(x => x.downcast_to<IEventSubscriber<Event>>())
- // .each(x => x.notify(the_event_to_broadcast));
+ process(() => subscribers.call_on_each<IEventSubscriber<Event>>(x => x.notify(the_event_to_broadcast)));
+ }
- listeners.call_on_each<IEventSubscriber<Event>>(x => x.notify(the_event_to_broadcast));
+ public void publish<T>(Action<T> call) where T : class
+ {
+ process(() => subscribers.each(x => x.call_on(call)));
}
public void publish<Event>() where Event : IEvent, new()
@@ -52,15 +52,6 @@ namespace MoMoney.Infrastructure.eventing
publish(new Event());
}
- //List<object> get_list_for<Event>()
- //{
- // if (!subscribers.ContainsKey(typeof (Event).FullName))
- // {
- // subscribers.Add(typeof (Event).FullName, new List<object>());
- // }
- // return subscribers[typeof (Event).FullName];
- //}
-
void within_lock(Action action)
{
lock (mutex)
@@ -68,5 +59,10 @@ namespace MoMoney.Infrastructure.eventing
action();
}
}
+
+ void process(Action action)
+ {
+ context.Send(x => action(), null);
+ }
}
}
\ No newline at end of file
trunk/product/MyMoney/Infrastructure/eventing/EventAggregatorSpecs.cs
@@ -1,3 +1,6 @@
+using System;
+using System.Data;
+using System.Threading;
using developwithpassion.bdd.contexts;
using MoMoney.Testing.spechelpers.contexts;
using MoMoney.Testing.spechelpers.core;
@@ -7,6 +10,10 @@ namespace MoMoney.Infrastructure.eventing
{
public class behaves_like_event_aggregator : concerns_for<IEventAggregator, EventAggregator>
{
+ public override IEventAggregator create_sut()
+ {
+ return new EventAggregator(new SynchronizationContext());
+ }
}
public class when_a_event_is_raised_in_the_system : behaves_like_event_aggregator
@@ -41,6 +48,27 @@ namespace MoMoney.Infrastructure.eventing
static IEventSubscriber<AnotherEvent> incorrect_subscriber;
}
+ public class when_publishing_a_call_to_all_subscribers : behaves_like_event_aggregator
+ {
+ it should_make_the_call_on_each_subscriber = () => connection.was_told_to(x => x.ChangeDatabase("localhost"));
+
+ context c = () =>
+ {
+ connection = an<IDbConnection>();
+ command = an<IDbCommand>();
+ };
+
+ because b = () =>
+ {
+ sut.subscribe(connection);
+ sut.subscribe(command);
+ sut.publish<IDbConnection>(x => x.ChangeDatabase("localhost"));
+ };
+
+ static IDbConnection connection;
+ static IDbCommand command;
+ }
+
public class TestEvent : IEvent
{
}