diff --git a/src/Spring/Spring.Core/Context/Support/AbstractApplicationContext.cs b/src/Spring/Spring.Core/Context/Support/AbstractApplicationContext.cs
index a9eba505..f8602d26 100644
--- a/src/Spring/Spring.Core/Context/Support/AbstractApplicationContext.cs
+++ b/src/Spring/Spring.Core/Context/Support/AbstractApplicationContext.cs
@@ -1821,6 +1821,31 @@ namespace Spring.Context.Support
_eventRegistry.Subscribe(subscriber, targetSourceType);
}
+
+ ///
+ /// Unsubscribes to all events published, if the subscriber
+ /// implmenets compatible handler methods.
+ ///
+ /// The subscriber to use
+ public void Unsubscribe(object subscriber)
+ {
+ _eventRegistry.Unsubscribe(subscriber);
+ }
+
+ ///
+ /// Unsubscribes to the published events of all objects of a given
+ /// , if the subscriber implements
+ /// compatible handler methods.
+ ///
+ /// The subscriber to use.
+ ///
+ /// The target to unsubscribe from
+ ///
+ public void Unsubscribe(object subscriber, Type targetSourceType)
+ {
+ _eventRegistry.Unsubscribe(subscriber, targetSourceType);
+ }
+
#endregion
///
diff --git a/src/Spring/Spring.Core/Objects/Events/IEventRegistry.cs b/src/Spring/Spring.Core/Objects/Events/IEventRegistry.cs
index be7c29a1..8bb7f259 100644
--- a/src/Spring/Spring.Core/Objects/Events/IEventRegistry.cs
+++ b/src/Spring/Spring.Core/Objects/Events/IEventRegistry.cs
@@ -53,6 +53,24 @@ namespace Spring.Objects.Events
///
/// The target to subscribe to.
///
- void Subscribe(object subscriber, Type targetSourceType);
+ void Subscribe(object subscriber, Type targetSourceType);
+
+ ///
+ /// Unsubscribes to all events published, if the subscriber
+ /// implmenets compatible handler methods.
+ ///
+ /// The subscriber to use
+ void Unsubscribe(object subscriber);
+
+ ///
+ /// Unsubscribes to the published events of all objects of a given
+ /// , if the subscriber implements
+ /// compatible handler methods.
+ ///
+ /// The subscriber to use.
+ ///
+ /// The target to unsubscribe from
+ ///
+ void Unsubscribe(object subscriber, Type targetSourceType);
}
}
\ No newline at end of file
diff --git a/src/Spring/Spring.Core/Objects/Events/Support/EventRegistry.cs b/src/Spring/Spring.Core/Objects/Events/Support/EventRegistry.cs
index 55253488..53450e95 100644
--- a/src/Spring/Spring.Core/Objects/Events/Support/EventRegistry.cs
+++ b/src/Spring/Spring.Core/Objects/Events/Support/EventRegistry.cs
@@ -28,97 +28,138 @@ using System.Reflection;
namespace Spring.Objects.Events.Support
{
- ///
- /// Default implementation of the
- /// interface.
- ///
- /// Griffin Caprio
- public class EventRegistry : IEventRegistry
- {
- private IList _publishers;
+ ///
+ /// Default implementation of the
+ /// interface.
+ ///
+ /// Griffin Caprio
+ public class EventRegistry : IEventRegistry
+ {
+ private IList _publishers;
- ///
- /// Creates a new instance of the EventRegistry class.
- ///
- public EventRegistry()
- {
- _publishers = new ArrayList();
- }
+ ///
+ /// Creates a new instance of the EventRegistry class.
+ ///
+ public EventRegistry()
+ {
+ _publishers = new ArrayList();
+ }
- ///
- /// The list of event publishers.
- ///
- /// The list of event publishers.
- protected IList Publishers
- {
- get { return _publishers; }
- }
+ ///
+ /// The list of event publishers.
+ ///
+ /// The list of event publishers.
+ protected IList Publishers
+ {
+ get { return _publishers; }
+ }
- ///
- /// Adds the input object to the list of publishers.
- ///
- ///
- /// This publishes all events of the source object to any object
- /// wishing to subscribe
- ///
- /// The source object to publish.
- public virtual void PublishEvents(object source)
- {
- Publishers.Add(source);
- }
+ ///
+ /// Adds the input object to the list of publishers.
+ ///
+ ///
+ /// This publishes all events of the source object to any object
+ /// wishing to subscribe
+ ///
+ /// The source object to publish.
+ public virtual void PublishEvents(object source)
+ {
+ Publishers.Add(source);
+ }
- ///
- /// Subscribes to all events published, if the subscriber implements
- /// compatible handler methods.
- ///
- /// The subscriber to use.
- public virtual void Subscribe(object subscriber)
- {
- Subscribe(subscriber, null);
- }
+ ///
+ /// Subscribes to all events published, if the subscriber implements
+ /// compatible handler methods.
+ ///
+ /// The subscriber to use.
+ public virtual void Subscribe(object subscriber)
+ {
+ Subscribe(subscriber, null);
+ }
- ///
- /// Subscribes to published events of all objects of a given type, if the
- /// subscriber implements compatible handler methods.
- ///
- /// The subscriber to use.
- ///
- /// The target to subscribe to.
- ///
- public virtual void Subscribe(object subscriber, Type sourceType)
- {
- Type currentSubscriberType = subscriber.GetType();
- foreach (object currentPublisher in _publishers)
- {
- if (null == sourceType
- || sourceType.IsAssignableFrom(currentPublisher.GetType()))
- {
- wireSubscriberToPublisher(
- currentPublisher, currentSubscriberType, subscriber);
- }
- }
- }
-
- private static void wireSubscriberToPublisher(
- object currentPublisher, Type currentSubscriberType, object subscriber)
- {
- Type currentPublisherType = currentPublisher.GetType();
- EventInfo[] events = currentPublisherType.GetEvents();
- foreach (EventInfo currentEvent in events)
- {
- Type eventHandlerType = currentEvent.EventHandlerType;
- MethodInfo invoke = eventHandlerType.GetMethod("Invoke");
- MethodInfo eventHandler
- = EventManipulationUtils.GetMethodInfoMatchingSignature(
- invoke, currentSubscriberType);
- if (eventHandler != null)
- {
- currentEvent.AddEventHandler(
- currentPublisher,
- EventManipulationUtils.GetHandlerDelegate(
- eventHandlerType, subscriber, eventHandler));
- }
- }
- }
- }
+ ///
+ /// Subscribes to published events of all objects of a given type, if the
+ /// subscriber implements compatible handler methods.
+ ///
+ /// The subscriber to use.
+ ///
+ /// The target to subscribe to.
+ ///
+ public virtual void Subscribe(object subscriber, Type sourceType)
+ {
+ Type currentSubscriberType = subscriber.GetType();
+ foreach (object currentPublisher in _publishers)
+ {
+ if (null == sourceType
+ || sourceType.IsAssignableFrom(currentPublisher.GetType()))
+ {
+ WireOrUnwireSubscriberToPublisher(
+ currentPublisher, currentSubscriberType, subscriber, true);
+ }
+ }
+ }
+
+ ///
+ /// Unsubscribes to all events published, if the subscriber
+ /// implmenets compatible handler methods.
+ ///
+ /// The subscriber to use
+ public virtual void Unsubscribe(object subscriber)
+ {
+ Unsubscribe(subscriber, null);
+ }
+
+ ///
+ /// Unsubscribes to the published events of all objects of a given
+ /// , if the subscriber implements
+ /// compatible handler methods.
+ ///
+ /// The subscriber to use.
+ /// The target to unsubscribe from
+ public virtual void Unsubscribe(object subscriber, Type sourceType)
+ {
+ Type currentSubscriberType = subscriber.GetType();
+ foreach (object currentPublisher in _publishers)
+ {
+ if (null == sourceType
+ || sourceType.IsAssignableFrom(currentPublisher.GetType()))
+ {
+ WireOrUnwireSubscriberToPublisher(
+ currentPublisher, currentSubscriberType, subscriber, false);
+ }
+ }
+ }
+
+ private static void WireOrUnwireSubscriberToPublisher(
+ object currentPublisher, Type currentSubscriberType, object subscriber, bool wire)
+ {
+ Type currentPublisherType = currentPublisher.GetType();
+ EventInfo[] events = currentPublisherType.GetEvents();
+ foreach (EventInfo currentEvent in events)
+ {
+ Type eventHandlerType = currentEvent.EventHandlerType;
+ MethodInfo invoke = eventHandlerType.GetMethod("Invoke");
+ MethodInfo eventHandler
+ = EventManipulationUtils.GetMethodInfoMatchingSignature(
+ invoke, currentSubscriberType);
+ if (eventHandler != null)
+ {
+ if (wire)
+ {
+ currentEvent.AddEventHandler(
+ currentPublisher,
+ EventManipulationUtils.GetHandlerDelegate(
+ eventHandlerType, subscriber, eventHandler));
+ }
+ else
+ {
+ currentEvent.RemoveEventHandler(
+ currentPublisher,
+ EventManipulationUtils.GetHandlerDelegate(
+ eventHandlerType, subscriber, eventHandler));
+ }
+ }
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/test/Spring/Spring.Core.Tests/Context/CommonTypes.cs b/test/Spring/Spring.Core.Tests/Context/CommonTypes.cs
index 7020d9f4..1bec58e6 100644
--- a/test/Spring/Spring.Core.Tests/Context/CommonTypes.cs
+++ b/test/Spring/Spring.Core.Tests/Context/CommonTypes.cs
@@ -584,11 +584,22 @@ namespace Spring.Context
throw new NotImplementedException();
}
- #endregion
-
public void PublishEvent(object sender, ApplicationEventArgs e)
{
throw new NotImplementedException();
}
- }
+
+
+ public void Unsubscribe(object subscriber)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Unsubscribe(object subscriber, Type targetSourceType)
+ {
+ throw new NotImplementedException();
+ }
+
+ #endregion
+ }
}
\ No newline at end of file
diff --git a/test/Spring/Spring.Core.Tests/Context/Support/ApplicationObjectSupportTests.cs b/test/Spring/Spring.Core.Tests/Context/Support/ApplicationObjectSupportTests.cs
index b02ce052..adf2e81f 100644
--- a/test/Spring/Spring.Core.Tests/Context/Support/ApplicationObjectSupportTests.cs
+++ b/test/Spring/Spring.Core.Tests/Context/Support/ApplicationObjectSupportTests.cs
@@ -325,7 +325,18 @@ namespace Spring.Context.Support
throw new NotImplementedException();
}
- #endregion
+
+ public void Unsubscribe(object subscriber)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Unsubscribe(object subscriber, Type targetSourceType)
+ {
+ throw new NotImplementedException();
+ }
+
+ #endregion
public void PublishEvent(object sender, ApplicationEventArgs e)
{
diff --git a/test/Spring/Spring.Core.Tests/Objects/Events/Support/EventRegistryTests.cs b/test/Spring/Spring.Core.Tests/Objects/Events/Support/EventRegistryTests.cs
index 9de96b59..9e6774de 100644
--- a/test/Spring/Spring.Core.Tests/Objects/Events/Support/EventRegistryTests.cs
+++ b/test/Spring/Spring.Core.Tests/Objects/Events/Support/EventRegistryTests.cs
@@ -111,13 +111,20 @@ namespace Spring.Objects.Events.Support.Tests
internal class SimpleSubscriber
{
+ protected int _eventCount;
+
protected bool _eventRaised = false;
public SimpleSubscriber()
{
}
- public bool EventRaised
+ public int EventCount
+ {
+ get { return _eventCount; }
+ }
+
+ public bool EventRaised
{
get { return _eventRaised; }
}
@@ -132,6 +139,7 @@ namespace Spring.Objects.Events.Support.Tests
public void HandleClientEvents(object sender, MyClientEventArgs args)
{
_eventRaised = true;
+ _eventCount++;
}
}
@@ -220,6 +228,28 @@ namespace Spring.Objects.Events.Support.Tests
Assert.IsTrue(sub2.EventRaised, "Event Not Raised");
}
+ [Test]
+ public void PublishAllEventsMultipleSubscribersAndUnsubscribe()
+ {
+ IEventRegistry registry = new EventRegistry();
+ SimpleClient client = new SimpleClient("PublishAllEvents");
+ registry.PublishEvents(client);
+ EventSubscriber sub = new EventSubscriber();
+ EventSubscriber sub2 = new EventSubscriber();
+ registry.Subscribe(sub);
+ registry.Subscribe(sub2);
+ client.ClientMethodThatTriggersEvent();
+ Assert.IsTrue(sub.EventRaised, "Event Not Raised");
+ Assert.IsTrue(sub2.EventRaised, "Event Not Raised");
+ Assert.AreEqual(1, sub.EventCount);
+ Assert.AreEqual(1, sub2.EventCount);
+
+ registry.Unsubscribe(sub2);
+ client.ClientMethodThatTriggersEvent();
+ Assert.AreEqual(2, sub.EventCount);
+ Assert.AreEqual(1, sub2.EventCount);
+ }
+
[Test]
public void PublishAllEventsSubscribeToNamedEvents()
{