using System; using System.Collections.Generic; using System.Text; namespace MT.Platform.Common { /// /// Manages list of notification subscriptions. Can be of local or remote kind. /// public sealed class Subscriptions { /// /// List of subscriptions /// private IList subscribers; /// /// Default Constructor /// public Subscriptions() { subscribers = new List(); } /// /// Add subscription to list /// /// public void Add(Subscription subscriber) { lock (this) { subscribers.Add(subscriber); } } /// /// Get a list of subscriptions of the specified type. Filters are not taken into account yet. /// Also return subscriptions for all type of notifications (type = null). /// /// Notification type or "null" type for all messages. /// List of subscriptions public IList Get(Type type) { IList getSubscribers = new List(); lock (this) { foreach (Subscription subscriber in this.subscribers) { // send to registered subscriptions // with all types if (type == null || (subscriber.NotificationType != null && subscriber.NotificationType.Equals(type)) || (type != null && subscriber.NotificationType == null)) { getSubscribers.Add(subscriber); } } } return getSubscribers; } /// /// Remove a subscription from the list /// /// public void Remove(Subscription subscriber) { Remove(subscriber.NotificationType); } /// /// Remove a delegate from local subscriptions in the list. /// /// The type of the notification. /// The handler for the notification. public void Remove(Type type, NotificationHandler handler) { IList removeList = new List(); lock (this) { // first the ones to remove foreach (Subscription subscription in subscribers) { LocalSubscription localSubscription = subscription as LocalSubscription; if (localSubscription != null) { if (localSubscription.NotificationType != null && localSubscription.NotificationType.Equals(type) && localSubscription.Handler.Equals(handler)) { removeList.Add(localSubscription); } } } } // then remove separately foreach (Subscription subscription in removeList) { RemoveOne(subscription); } } /// /// Removes and disposes one subscription. /// /// private void RemoveOne(Subscription subscription) { lock (this) { // remove from list subscribers.Remove(subscription); // and dispose IDisposable disposableSubscription = subscription as IDisposable; if (disposableSubscription != null) { disposableSubscription.Dispose(); } } } /// /// Remove all subscription for the given type from the list /// /// The type of the notification to remove. public void Remove(Type type) { IList removeList = new List(); lock (this) { // first the ones to remove foreach (Subscription subscription in subscribers) { if (subscription.NotificationType != null && subscription.NotificationType.Equals(type)) { removeList.Add(subscription); } } } // then remove separately foreach (Subscription subscription in removeList) { RemoveOne(subscription); } } /// /// Remove and disposes all subscriptions. /// public void Clear() { lock (this) { IList removeList = new List(); // get the ones to remove in separate list. Cannot loop over a list and remove items ...! foreach (Subscription subscription in subscribers) { removeList.Add(subscription); } // then remove separately foreach (Subscription subscription in removeList) { RemoveOne(subscription); } } } } }