FunCoding.CoreMessenger 0.1.4

There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package FunCoding.CoreMessenger --version 0.1.4
                    
NuGet\Install-Package FunCoding.CoreMessenger -Version 0.1.4
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="FunCoding.CoreMessenger" Version="0.1.4" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="FunCoding.CoreMessenger" Version="0.1.4" />
                    
Directory.Packages.props
<PackageReference Include="FunCoding.CoreMessenger" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add FunCoding.CoreMessenger --version 0.1.4
                    
#r "nuget: FunCoding.CoreMessenger, 0.1.4"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package FunCoding.CoreMessenger@0.1.4
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=FunCoding.CoreMessenger&version=0.1.4
                    
Install as a Cake Addin
#tool nuget:?package=FunCoding.CoreMessenger&version=0.1.4
                    
Install as a Cake Tool

CoreMessenger

A simple messenger system for WPF, UWP and Xamarin. .NET Standard supported.

This project comes from MvvmCross.Messenger and now it can be used in all the WPF, UWP and Xamarin projects without MvvmCross. The original inspiration for this code was XPlatUtils from JonathonPeppers - https://github.com/jonathanpeppers/XPlatUtils

Usage

Install from Nuget:

PM> Install-Package FunCoding.CoreMessenger

Use MessengerHub.Instance as the singleton pattern in your whole app domain. It provides these methods:

  • Publish:
public async Task Publish<TMessage>(TMessage message)
  • Subscribe:
public SubscriptionToken Subscribe<TMessage>(Action<TMessage> action, ReferenceType referenceType = ReferenceType.Weak, SubscriptionPriority priority = SubscriptionPriority.Normal, string tag = null)
  • Unsubscribe:
public async Task Unsubscribe<TMessage>(SubscriptionToken subscriptionToken)

Creating the Message class

First, define a Message class inherited from Message between different components, like this:

public class TestMessage : Message
{
    public string ExtraContent { get; private set; }
    public TestMessage(object sender, string content) : base(sender)
    {
        ExtraContent = content;
    }
}

Then create an instance of the Message in your component A, as shown below:

var message = new TestMessage(this, "Test Content");

Subscription

Define a SubscriptionToken instance to store the subscription. Subscribe the Message in your component B, like this:

public class HomeViewModel
    {
        private readonly SubscriptionToken _subscriptionTokenForTestMessage;
        public HomeViewModel()
        {
            _subscriptionTokenForTestMessage = 
                MessengerHub.Instance.Subscribe<TestMessage>(OnTestMessageReceived,
                ReferenceType.Weak, SubscriptionPriority.Normal);
        }

        private void OnTestMessageReceived(TestMessage message)
        {
#if DEBUG
            System.Diagnostics.Debug.WriteLine($"Received messages of type {message.GetType().ToString()}. Content: {message.Content}");
#endif
        }
    }

Publishing the Message

Publish the Message in your component A:

public async Task PublishMessage()
{
    await MessengerHub.Instance.Publish(new TestMessage(this, $"Hello World!"));
}

All done!

Parameters

The full singnature of the Subscribe method is:

public SubscriptionToken Subscribe<TMessage>(Action<TMessage> action,
            ReferenceType referenceType = ReferenceType.Weak,
            SubscriptionPriority priority = SubscriptionPriority.Normal, string tag = null) where TMessage : Message

You can specify these parameters:

  • ReferenceType. The default value is ReferenceType.Weak so you do not need to worry about the memory leaking. Once the SubscriptionToken instance goes out of the scope, GC can collect it automatically(But not sure when). If you need to keep a strong reference, specify the parameter as ReferenceType.Strong so that GC cannot collect it.
  • SubscriptionPriority. The default value is SubscriptionPriority.Normal. Sometimes it is required to control the excution orders of the subscriptions for one Message. In this case, specify different priorities for the subscriptions to control the excution orders. Notice that this parameter is not for different Messages.
  • Tag. It is optional to inspect current status for subscriptions.

Unsubscribe

You can use these methods to unsubscribe the subscription:

  • Use Unsubscribe method, as shown below:
    await MessengerHub.Instance.Unsubscribe<TestMessage>(_subscriptionTokenForTestMessage);
    
  • Use Dispose method of the SubscriptionToken:
    _subscriptionTokenForTestMessage.Dispose();
    

In many scenarios, you will not call these methods directly. If you are using the strong subscription type, it might cause memory leaking issue. So ReferenceType.Weak is recommended. Be aware that if the token is not stored in the context, it might be collected by GC immediately. For example:

public void MayNotEverReceiveAMessage()
{
    var token = MessengerHub.Instance.Subscribe<TestMessage>((message) => {
        // Do something here
    });
    // token goes out of scope now
    // - so will be garbage collected *at some point*
    // - so the action may never get called
}

Differences with MvvmCross.Messenger

If you are using MvvmCross to develop your application, please use MvvmCross.Messenger directly. I extracted some main methods and removed dependencies to MvvmCross components so it can be used in any WPF, UWP and Xamarin projects without MvvmCross. Also the Publish method is always running in background to avoid blocking the UI. Another difference is that no need to use DI to create the instance of MessageHub which is a singleton instance in all the app domain. It is useful if the solution contains multiple components that need communicate with each other. DI would make it more complicated.

Thanks

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0-CI-20191202-034430 484 12/2/2019
0.1.4 1,601 10/6/2019

The first version.