Can MvvmCross Messenger be used without IoC?

112 views Asked by At

I would like to use MvvmCross Messenger to send messages between addins I'm developing for for an app whose source I cannot modify.

As such, I don't see a clear way to use IoC, so I would just roll my own singleton.

However my simple test gets an exception when I call Subscribe.

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var m = new MvxMessengerHub();
            // exception on Subscribe: 
            // The type initializer for 'MvvmCross.Plugin.Messenger.MvxPluginLog' threw an exception.
            m.Subscribe<TestMessage>((msg) =>
            {
                Debug.Print("got msg");
            });
            m.Publish<TestMessage>(new TestMessage(this));
        }
    }
    public class TestMessage : MvxMessage
    {        
        public TestMessage(object sender): base(sender)
        {
        }
    }

Should the doc say "can only" instead of "can"?

enter image description here


Here's the stack trace:

The type initializer for 'MvvmCross.Plugin.Messenger.MvxPluginLog' threw an exception.
   at MvvmCross.Plugin.Messenger.MvxPluginLog.get_Instance() in /_/MvvmCross.Plugins/Messenger/MvxPluginLog.cs:line 11
   at MvvmCross.Plugin.Messenger.MvxMessengerHub.SubscribeInternal[TMessage](Action`1 deliveryAction, IMvxActionRunner actionRunner, MvxReference reference, String tag) in /_/MvvmCross.Plugins/Messenger/MvxMessengerHub.cs:line 75
   at MvvmCross.Plugin.Messenger.MvxMessengerHub.Subscribe[TMessage](Action`1 deliveryAction, MvxReference reference, String tag) in /_/MvvmCross.Plugins/Messenger/MvxMessengerHub.cs:line 29
   at WpfApp1.MainWindow.Button_Click(Object sender, RoutedEventArgs e) in D:\repos\esri\arcgis-pro-sdk-cim-viewer\WpfApp1\MainWindow.xaml.cs:line 40

Update: I found this test from someone else's project from 5 yrs ago, so it seems like this must have worked in a previous version.

public void SubscribeAndPublishAllowsMessageToBeReceived()
{
    var messenger = new MvxMessengerHub();
    var message = new TestMessage(this);

    var messageReceived = false;
    messenger.Subscribe<TestMessage>(m =>
        {
            Assert.That(m, Is.EqualTo(message));
            Assert.That(m.Sender, Is.EqualTo(this));
            messageReceived = true;
        });

    messenger.Publish(message);

    Assert.IsTrue(messageReceived);
}

1

There are 1 answers

0
Trevor Balcom On

If you look at the source, you will see MvxMessengerHub references MvxPluginLog.Instance to write log messages. The exception is being thrown because MvxPlugingLog.Instance.get is being called internally by MvxMessengerHub at various points. MvxPluginLog.Instance.get is using MvvmCross IoC container to resolve IMvxLogProvider. You could provide your own implementation of IMvxMessengerHub that does not use MvxPluginLog.Instance.