Commit d7fe04b

mokhan <mokhan@ce5e1baf-6525-42e4-a1b2-857ea38da20a>
2009-03-26 23:45:56
cleaned up the event aggregator.
git-svn-id: https://svn.xp-dev.com/svn/mokhan-mo.money@113 ce5e1baf-6525-42e4-a1b2-857ea38da20a
1 parent dd4d055
Changed files (2)
trunk
product
MyMoney
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
     {
     }