[英]MVVMCross Messenger - Subscribing to messages in static class
我只是在考慮實施MVVMCross Messenger解決方案,當從iOS應用程序或PCL發布時,該解決方案使我能夠將信息上傳到Google Analytics(分析)。
我的問題是發布后未觸發訂閱代理。 您可以從靜態類訂閱MVVMCross Messenger訂閱嗎?
靜態類中的訂閱
public static class GoogleAnalyticsWrapper //: IDisposable
{
private const string TrackingId = "xxxxxxxxxxx";
private static readonly IMvxMessenger messenger;
private static readonly MvxSubscriptionToken screenNameToken;
private static readonly MvxSubscriptionToken eventToken;
private static readonly MvxSubscriptionToken exceptionToken;
private static readonly MvxSubscriptionToken performanceToken;
private static readonly MvxSubscriptionToken publishToken;
private static bool disposed = false;
private static SafeHandle handle;
static GoogleAnalyticsWrapper()
{
Gai.SharedInstance.DispatchInterval = 60;
Gai.SharedInstance.TrackUncaughtExceptions = true;
Gai.SharedInstance.GetTracker(TrackingId);
messenger = new MvxMessengerHub();// Mvx.Resolve<IMvxMessenger>();
screenNameToken = messenger.Subscribe<GaScreenNameMessage>((m) => SetScreenName(m));
int count = messenger.CountSubscriptionsFor<GaScreenNameMessage>();
eventToken = messenger.Subscribe<GaEventMessage>(CreateEvent);
exceptionToken = messenger.Subscribe<GaExceptionMessage>(CreateException);
performanceToken = messenger.Subscribe<GaPerformanceTimingMessage>(CreatePerformanceMetric);
publishToken = messenger.Subscribe<GaPublishMessage>(PublishAll);
}
public static string Dummy { get; set; }
public static void SetScreenName(GaScreenNameMessage message)
{
System.Diagnostics.Debugger.Break();
Gai.SharedInstance.DefaultTracker.Set(GaiConstants.ScreenName, message.ScreenName);
Gai.SharedInstance.DefaultTracker.Send(DictionaryBuilder.CreateScreenView().Build());
}
public static void CreateEvent(GaEventMessage message)
=> Gai.SharedInstance.DefaultTracker.Send(DictionaryBuilder.CreateEvent(message.Category, message.Action, message.Label, message.Number).Build());
private static void CreateException(GaExceptionMessage message)
=> Gai.SharedInstance.DefaultTracker.Send(DictionaryBuilder.CreateException(message.ExceptionMessage, message.IsFatal).Build());
private static void CreatePerformanceMetric(GaPerformanceTimingMessage message)
=> Gai.SharedInstance.DefaultTracker.Send(DictionaryBuilder.CreateTiming(message.Category, message.Milliseconds, message.Name, message.Label).Build());
private static void PublishAll(GaPublishMessage message)
=> Gai.SharedInstance.Dispatch();
public static void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// Dispose managed resources.
if (handle != null)
{
handle.Dispose();
}
}
// Dispose unmanaged managed resources.
disposed = true;
}
}
}
出版物
messengerService.Publish<GaEventMessage>(new GaEventMessage(this, "Event", "Publish Event", "Publish Event From First View Model", 123));
問題是,您正在靜態類中創建一個新的MvxMessengerHub
,但是( 我猜是 )將IMvxMessenger
注入到您的使用類中,該類是由MvvMCross在初始化生命周期內創建的,因此是另一個實例。
簡單的解決方案是在App.cs中將其初始化,例如
public class App : Cirrious.MvvmCross.ViewModels.MvxApplication
{
public override void Initialize()
{
// ...
var m = Cirrious.CrossCore.Mvx.Resolve<IMvxMessenger>();
GoogleAnalyticsWrapper.Initialize(m);
// ...
}
}
用這樣的包裝紙
public static class GoogleAnalyticsWrapper
{
static void Initialize(IMvxMessenger messenger)
{
Gai.SharedInstance.DispatchInterval = 60;
Gai.SharedInstance.TrackUncaughtExceptions = true;
Gai.SharedInstance.GetTracker(TrackingId);
screenNameToken = messenger.Subscribe<GaScreenNameMessage>((m) => SetScreenName(m));
int count = messenger.CountSubscriptionsFor<GaScreenNameMessage>();
eventToken = messenger.Subscribe<GaEventMessage>(CreateEvent);
exceptionToken = messenger.Subscribe<GaExceptionMessage>(CreateException);
performanceToken = messenger.Subscribe<GaPerformanceTimingMessage>(CreatePerformanceMetric);
publishToken = messenger.Subscribe<GaPublishMessage>(PublishAll);
}
// ...
}
但是據我所知,在這種情況下,您甚至不需要消息傳遞,因為它是一對一的“通信”。 如果您將GoogleAnalyticsWrapper的功能移入定義明確的服務中,例如:
interface ITrackingService
{
void SetScreenName(GaScreenNameMessage message);
void CreateEvent(GaEventMessage message);
void CreateException(GaExceptionMessage message);
void CreatePerformanceMetric(GaPerformanceTimingMessage message);
void PublishAll(GaPublishMessage message);
}
public class GoogleAnalyticsTrackingService : ITrackingService
{
private const string TrackingId = "xxxxxxxxxxx";
public GoogleAnalyticsTrackingService()
{
Gai.SharedInstance.DispatchInterval = 60;
Gai.SharedInstance.TrackUncaughtExceptions = true;
Gai.SharedInstance.GetTracker(TrackingId);
}
public void SetScreenName(GaScreenNameMessage message)
{
Gai.SharedInstance.DefaultTracker.Set(GaiConstants.ScreenName, message.ScreenName);
Gai.SharedInstance.DefaultTracker.Send(DictionaryBuilder.CreateScreenView().Build());
}
public void CreateEvent(GaEventMessage message)
{
Gai.SharedInstance.DefaultTracker.Send(DictionaryBuilder.CreateEvent(message.Category, message.Action, message.Label, message.Number).Build());
}
private void CreateException(GaExceptionMessage message)
{
Gai.SharedInstance.DefaultTracker.Send(DictionaryBuilder.CreateException(message.ExceptionMessage, message.IsFatal).Build());
}
private void CreatePerformanceMetric(GaPerformanceTimingMessage message)
{
Gai.SharedInstance.DefaultTracker.Send(DictionaryBuilder.CreateTiming(message.Category, message.Milliseconds, message.Name, message.Label).Build());
}
private void PublishAll(GaPublishMessage message)
{
Gai.SharedInstance.Dispatch();
}
}
必須在您的應用中注冊
Mvx.LazyConstructAndRegisterSingleton<ITrackingService, GoogleAnalyticsTrackingService>();
可以與構造函數注入或手動解析一起使用
class MyViewModel : MvxViewModel
{
public MyViewModel(ITrackingService tracking)
{
tracking.CreateEvent(new GaEventMessage(this, "Event", "Publish Event", "Publish Event From First View Model", 123));
}
}
// or
class MyViewModel : MvxViewModel
{
public MyViewModel()
{
var tracking = Mvx.Resolve<ITrackingService>();
tracking.CreateEvent(new GaEventMessage(this, "Event", "Publish Event", "Publish Event From First View Model", 123));
}
}
仍然存在一個問題:界面仍然依賴於Google Analytics(分析)。 但是可以通過使用多個參數而不是參數對象來輕松刪除依賴項。
interface ITrackingService
{
void CreateEvent(string eventName, string title, string message, params object[] additionalParams);
// ...
}
// call:
tracking.CreateEvent("Event", "Publish Event", "Publish Event From First View Model", 123);
這樣,如果您的涉眾決定切換到Adobe omniture或其他工具,您就可以對它進行單元測試並輕松地交換跟蹤服務。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.