diff options
author | E.Z. Hart <hartez@users.noreply.github.com> | 2017-01-31 06:10:28 -0700 |
---|---|---|
committer | Rui Marinho <me@ruimarinho.net> | 2017-01-31 13:10:28 +0000 |
commit | b4fe4e0c902177ff7c175f691a5304d7c7ef518d (patch) | |
tree | 50bbf0a4c2ff4fef7492f3ba0dee9f7d0c445d67 /Xamarin.Forms.Core/MessagingCenter.cs | |
parent | d80be6fdb228567cc372e6c242052a6ba5853681 (diff) | |
download | xamarin-forms-b4fe4e0c902177ff7c175f691a5304d7c7ef518d.tar.gz xamarin-forms-b4fe4e0c902177ff7c175f691a5304d7c7ef518d.tar.bz2 xamarin-forms-b4fe4e0c902177ff7c175f691a5304d7c7ef518d.zip |
Make MessagingCenter testable (#723)
* Make MessagingCenter testable
* Eagerly create MessagingCenter instancef
* More succinct version
Diffstat (limited to 'Xamarin.Forms.Core/MessagingCenter.cs')
-rw-r--r-- | Xamarin.Forms.Core/MessagingCenter.cs | 89 |
1 files changed, 69 insertions, 20 deletions
diff --git a/Xamarin.Forms.Core/MessagingCenter.cs b/Xamarin.Forms.Core/MessagingCenter.cs index b6a167da..d5753e1d 100644 --- a/Xamarin.Forms.Core/MessagingCenter.cs +++ b/Xamarin.Forms.Core/MessagingCenter.cs @@ -2,12 +2,28 @@ using System; using System.Collections.Generic; using System.Linq; using System.Reflection; -using System.Runtime.CompilerServices; namespace Xamarin.Forms { - public static class MessagingCenter + public interface IMessagingCenter { + void Send<TSender, TArgs>(TSender sender, string message, TArgs args) where TSender : class; + + void Send<TSender>(TSender sender, string message) where TSender : class; + + void Subscribe<TSender, TArgs>(object subscriber, string message, Action<TSender, TArgs> callback, TSender source = null) where TSender : class; + + void Subscribe<TSender>(object subscriber, string message, Action<TSender> callback, TSender source = null) where TSender : class; + + void Unsubscribe<TSender, TArgs>(object subscriber, string message) where TSender : class; + + void Unsubscribe<TSender>(object subscriber, string message) where TSender : class; + } + + public class MessagingCenter : IMessagingCenter + { + public static IMessagingCenter Instance { get; } = new MessagingCenter(); + class Sender : Tuple<string, Type, Type> { public Sender(string message, Type senderType, Type argType) : base(message, senderType, argType) @@ -19,8 +35,8 @@ namespace Xamarin.Forms class MaybeWeakReference { - WeakReference DelegateWeakReference { get; set; } - object DelegateStrongReference { get; set; } + WeakReference DelegateWeakReference { get; } + object DelegateStrongReference { get; } readonly bool _isStrongReference; @@ -84,11 +100,16 @@ namespace Xamarin.Forms } } - static readonly Dictionary<Sender, List<Subscription>> s_subscriptions = + readonly Dictionary<Sender, List<Subscription>> _subscriptions = new Dictionary<Sender, List<Subscription>>(); public static void Send<TSender, TArgs>(TSender sender, string message, TArgs args) where TSender : class { + Instance.Send(sender, message, args); + } + + void IMessagingCenter.Send<TSender, TArgs>(TSender sender, string message, TArgs args) + { if (sender == null) throw new ArgumentNullException(nameof(sender)); InnerSend(message, typeof(TSender), typeof(TArgs), sender, args); @@ -96,6 +117,11 @@ namespace Xamarin.Forms public static void Send<TSender>(TSender sender, string message) where TSender : class { + Instance.Send(sender, message); + } + + void IMessagingCenter.Send<TSender>(TSender sender, string message) + { if (sender == null) throw new ArgumentNullException(nameof(sender)); InnerSend(message, typeof(TSender), null, sender, null); @@ -103,6 +129,11 @@ namespace Xamarin.Forms public static void Subscribe<TSender, TArgs>(object subscriber, string message, Action<TSender, TArgs> callback, TSender source = null) where TSender : class { + Instance.Subscribe(subscriber, message, callback, source); + } + + void IMessagingCenter.Subscribe<TSender, TArgs>(object subscriber, string message, Action<TSender, TArgs> callback, TSender source) + { if (subscriber == null) throw new ArgumentNullException(nameof(subscriber)); if (callback == null) @@ -121,6 +152,11 @@ namespace Xamarin.Forms public static void Subscribe<TSender>(object subscriber, string message, Action<TSender> callback, TSender source = null) where TSender : class { + Instance.Subscribe(subscriber, message, callback, source); + } + + void IMessagingCenter.Subscribe<TSender>(object subscriber, string message, Action<TSender> callback, TSender source) + { if (subscriber == null) throw new ArgumentNullException(nameof(subscriber)); if (callback == null) @@ -139,27 +175,32 @@ namespace Xamarin.Forms public static void Unsubscribe<TSender, TArgs>(object subscriber, string message) where TSender : class { + Instance.Unsubscribe<TSender, TArgs>(subscriber, message); + } + + void IMessagingCenter.Unsubscribe<TSender, TArgs>(object subscriber, string message) + { InnerUnsubscribe(message, typeof(TSender), typeof(TArgs), subscriber); } public static void Unsubscribe<TSender>(object subscriber, string message) where TSender : class { - InnerUnsubscribe(message, typeof(TSender), null, subscriber); + Instance.Unsubscribe<TSender>(subscriber, message); } - internal static void ClearSubscribers() + void IMessagingCenter.Unsubscribe<TSender>(object subscriber, string message) { - s_subscriptions.Clear(); + InnerUnsubscribe(message, typeof(TSender), null, subscriber); } - static void InnerSend(string message, Type senderType, Type argType, object sender, object args) + void InnerSend(string message, Type senderType, Type argType, object sender, object args) { if (message == null) throw new ArgumentNullException(nameof(message)); var key = new Sender(message, senderType, argType); - if (!s_subscriptions.ContainsKey(key)) + if (!_subscriptions.ContainsKey(key)) return; - List<Subscription> subcriptions = s_subscriptions[key]; + List<Subscription> subcriptions = _subscriptions[key]; if (subcriptions == null || !subcriptions.Any()) return; // should not be reachable @@ -178,24 +219,24 @@ namespace Xamarin.Forms } } - static void InnerSubscribe(object subscriber, string message, Type senderType, Type argType, object target, MethodInfo methodInfo, Filter filter) + void InnerSubscribe(object subscriber, string message, Type senderType, Type argType, object target, MethodInfo methodInfo, Filter filter) { if (message == null) throw new ArgumentNullException(nameof(message)); var key = new Sender(message, senderType, argType); var value = new Subscription(subscriber, target, methodInfo, filter); - if (s_subscriptions.ContainsKey(key)) + if (_subscriptions.ContainsKey(key)) { - s_subscriptions[key].Add(value); + _subscriptions[key].Add(value); } else { var list = new List<Subscription> { value }; - s_subscriptions[key] = list; + _subscriptions[key] = list; } } - static void InnerUnsubscribe(string message, Type senderType, Type argType, object subscriber) + void InnerUnsubscribe(string message, Type senderType, Type argType, object subscriber) { if (subscriber == null) throw new ArgumentNullException(nameof(subscriber)); @@ -203,11 +244,19 @@ namespace Xamarin.Forms throw new ArgumentNullException(nameof(message)); var key = new Sender(message, senderType, argType); - if (!s_subscriptions.ContainsKey(key)) + if (!_subscriptions.ContainsKey(key)) return; - s_subscriptions[key].RemoveAll(sub => sub.CanBeRemoved() || sub.Subscriber.Target == subscriber); - if (!s_subscriptions[key].Any()) - s_subscriptions.Remove(key); + _subscriptions[key].RemoveAll(sub => sub.CanBeRemoved() || sub.Subscriber.Target == subscriber); + if (!_subscriptions[key].Any()) + _subscriptions.Remove(key); + } + + // This is a bit gross; it only exists to support the unit tests in PageTests + // because the implementations of ActionSheet, Alert, and IsBusy are all very + // tightly coupled to the MessagingCenter singleton + internal static void ClearSubscribers() + { + (Instance as MessagingCenter)?._subscriptions.Clear(); } } }
\ No newline at end of file |