SPRNET-547 - Add Unsubscribe functionality to IEventRegistry
This commit is contained in:
@@ -1821,6 +1821,31 @@ namespace Spring.Context.Support
|
||||
_eventRegistry.Subscribe(subscriber, targetSourceType);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Unsubscribes to <b>all</b> events published, if the subscriber
|
||||
/// implmenets compatible handler methods.
|
||||
/// </summary>
|
||||
/// <param name="subscriber">The subscriber to use</param>
|
||||
public void Unsubscribe(object subscriber)
|
||||
{
|
||||
_eventRegistry.Unsubscribe(subscriber);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unsubscribes to the published events of all objects of a given
|
||||
/// <see cref="System.Type"/>, if the subscriber implements
|
||||
/// compatible handler methods.
|
||||
/// </summary>
|
||||
/// <param name="subscriber">The subscriber to use.</param>
|
||||
/// <param name="targetSourceType">
|
||||
/// The target <see cref="System.Type"/> to unsubscribe from
|
||||
/// </param>
|
||||
public void Unsubscribe(object subscriber, Type targetSourceType)
|
||||
{
|
||||
_eventRegistry.Unsubscribe(subscriber, targetSourceType);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -53,6 +53,24 @@ namespace Spring.Objects.Events
|
||||
/// <param name="targetSourceType">
|
||||
/// The target <see cref="System.Type"/> to subscribe to.
|
||||
/// </param>
|
||||
void Subscribe(object subscriber, Type targetSourceType);
|
||||
void Subscribe(object subscriber, Type targetSourceType);
|
||||
|
||||
/// <summary>
|
||||
/// Unsubscribes to <b>all</b> events published, if the subscriber
|
||||
/// implmenets compatible handler methods.
|
||||
/// </summary>
|
||||
/// <param name="subscriber">The subscriber to use</param>
|
||||
void Unsubscribe(object subscriber);
|
||||
|
||||
/// <summary>
|
||||
/// Unsubscribes to the published events of all objects of a given
|
||||
/// <see cref="System.Type"/>, if the subscriber implements
|
||||
/// compatible handler methods.
|
||||
/// </summary>
|
||||
/// <param name="subscriber">The subscriber to use.</param>
|
||||
/// <param name="targetSourceType">
|
||||
/// The target <see cref="System.Type"/> to unsubscribe from
|
||||
/// </param>
|
||||
void Unsubscribe(object subscriber, Type targetSourceType);
|
||||
}
|
||||
}
|
||||
@@ -28,97 +28,138 @@ using System.Reflection;
|
||||
|
||||
namespace Spring.Objects.Events.Support
|
||||
{
|
||||
/// <summary>
|
||||
/// Default implementation of the <see cref="Spring.Objects.Events.IEventRegistry"/>
|
||||
/// interface.
|
||||
/// </summary>
|
||||
/// <author>Griffin Caprio</author>
|
||||
public class EventRegistry : IEventRegistry
|
||||
{
|
||||
private IList _publishers;
|
||||
/// <summary>
|
||||
/// Default implementation of the <see cref="Spring.Objects.Events.IEventRegistry"/>
|
||||
/// interface.
|
||||
/// </summary>
|
||||
/// <author>Griffin Caprio</author>
|
||||
public class EventRegistry : IEventRegistry
|
||||
{
|
||||
private IList _publishers;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the EventRegistry class.
|
||||
/// </summary>
|
||||
public EventRegistry()
|
||||
{
|
||||
_publishers = new ArrayList();
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new instance of the EventRegistry class.
|
||||
/// </summary>
|
||||
public EventRegistry()
|
||||
{
|
||||
_publishers = new ArrayList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The list of event publishers.
|
||||
/// </summary>
|
||||
/// <value>The list of event publishers.</value>
|
||||
protected IList Publishers
|
||||
{
|
||||
get { return _publishers; }
|
||||
}
|
||||
/// <summary>
|
||||
/// The list of event publishers.
|
||||
/// </summary>
|
||||
/// <value>The list of event publishers.</value>
|
||||
protected IList Publishers
|
||||
{
|
||||
get { return _publishers; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the input object to the list of publishers.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This publishes <b>all</b> events of the source object to any object
|
||||
/// wishing to subscribe
|
||||
/// </remarks>
|
||||
/// <param name="source">The source object to publish.</param>
|
||||
public virtual void PublishEvents(object source)
|
||||
{
|
||||
Publishers.Add(source);
|
||||
}
|
||||
/// <summary>
|
||||
/// Adds the input object to the list of publishers.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This publishes <b>all</b> events of the source object to any object
|
||||
/// wishing to subscribe
|
||||
/// </remarks>
|
||||
/// <param name="source">The source object to publish.</param>
|
||||
public virtual void PublishEvents(object source)
|
||||
{
|
||||
Publishers.Add(source);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subscribes to <b>all</b> events published, if the subscriber implements
|
||||
/// compatible handler methods.
|
||||
/// </summary>
|
||||
/// <param name="subscriber">The subscriber to use.</param>
|
||||
public virtual void Subscribe(object subscriber)
|
||||
{
|
||||
Subscribe(subscriber, null);
|
||||
}
|
||||
/// <summary>
|
||||
/// Subscribes to <b>all</b> events published, if the subscriber implements
|
||||
/// compatible handler methods.
|
||||
/// </summary>
|
||||
/// <param name="subscriber">The subscriber to use.</param>
|
||||
public virtual void Subscribe(object subscriber)
|
||||
{
|
||||
Subscribe(subscriber, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subscribes to published events of all objects of a given type, if the
|
||||
/// subscriber implements compatible handler methods.
|
||||
/// </summary>
|
||||
/// <param name="subscriber">The subscriber to use.</param>
|
||||
/// <param name="sourceType">
|
||||
/// The target <see cref="System.Type"/> to subscribe to.
|
||||
/// </param>
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Subscribes to published events of all objects of a given type, if the
|
||||
/// subscriber implements compatible handler methods.
|
||||
/// </summary>
|
||||
/// <param name="subscriber">The subscriber to use.</param>
|
||||
/// <param name="sourceType">
|
||||
/// The target <see cref="System.Type"/> to subscribe to.
|
||||
/// </param>
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unsubscribes to <b>all</b> events published, if the subscriber
|
||||
/// implmenets compatible handler methods.
|
||||
/// </summary>
|
||||
/// <param name="subscriber">The subscriber to use</param>
|
||||
public virtual void Unsubscribe(object subscriber)
|
||||
{
|
||||
Unsubscribe(subscriber, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unsubscribes to the published events of all objects of a given
|
||||
/// <see cref="System.Type"/>, if the subscriber implements
|
||||
/// compatible handler methods.
|
||||
/// </summary>
|
||||
/// <param name="subscriber">The subscriber to use.</param>
|
||||
/// <param name="sourceType">The target <see cref="System.Type"/> to unsubscribe from</param>
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user