Messenger
Messenger
is another toolkit characteri ViewModel
property and is one of the main advantages of Fluent MVVM.
The Fluent MVVM Messenger engine is another toolkit characteristic, tries simply and ease to send and receive info between classes.
With Fluent MVVM Messenger engine any object can be sender, can be subscribe and can be object message, only needs a key
for identify the message.
It is localized in MoralesLarios.FluentMVVM.Messages
namespace and its principal class is MessengerManager
. MessengerManager
is a singleton class with ‘_’ (represented with underscore as singleton property name). This singleton can be injected for dependency injection and surprise its dependency call singleton.
MessengerManager
is designed for gain development speed and save time to developer but if you are a purist developer, MessegerManager
has generics methods versions.
MessengerManager
has 3 methods kinds, Senders, Subscribers and Unsubscribes. We will analyze these methods for pairs, (Send – Subscribe) to better understand how it works. Finally we will see Unsubscribe methods.
Messenger Example Project
For our Messenger example, we choose a ViewBag Porperty reduce version.
It's very simple app, one data list with a simple filter and reset filter. We will not explain this simple implementation, for more info, view example code in the section end, or ViewBag Porperty section.
We are going to focus in Messenger
characteristics.
IMessengerManager
IMessengerManager
, is the most important Fluent MVVM Messenger Interface.
In the following sections, we will see its most important methods.
This is your code:
public interface IMessengerManager { bool ExistsByKey(string key); bool ExistsByKeyEmisor(string key, [CallerFilePath] string emisor = ""); void Send(string key); void Send(string key, Action callback); void Send<TCallback>(string key, Action<TCallback> callback); void Send<TMessage>(string key, TMessage messageObject); void Send<TMessage>(string key, TMessage messageObject, Action callback); void Send<TMessage, TCallback>(string key, TMessage messageObject, Action<TCallback> callback); void SendAnonymous(string key, object messageAnnonimous); void SendAnonymous(string key, object messageAnnonimous, Action<dynamic> callbackAnonymous); void Subscribe(string key, Action action, [CallerFilePath] string emisor = "", bool isOverwrite = true); void Subscribe<TMessage>(string key, Action<TMessage> action, [CallerFilePath] string emisor = "", bool isOverwrite = true); void SubscribeWithCallback(string key, Action<Action> actionWithCallbackParameter, [CallerFilePath] string emisor = "", bool isOverwrite = true); void SubscribeWithCallback<TMessage>(string key, Action<TMessage, Action> actionWithCallbackParameter, [CallerFilePath] string emisor = "", bool isOverwrite = true); void SubscribeWithCallback<TCallback>(string key, Action<Action<TCallback>> actionWithCallbackParameter, [CallerFilePath] string emisor = "", bool isOverwrite = true); void SubscribeWithCallback<TMessage, TCallback>(string key, Action<TMessage, Action<TCallback>> actionWithCallbackParameter, [CallerFilePath] string emisor = "", bool isOverwrite = true); void SubscribeAnonymous(string key, Action<dynamic> actionAnonymous, [CallerFilePath] string emisor = "", bool isOverwrite = true); void SubscribeAnonymousWithCallback(string key, Action<dynamic, Action<dynamic>> actionWithCallbackAnonymous, [CallerFilePath] string emisor = "", bool isOverwrite = true); void Unsubscribe(string key); void Unsubscribe(string key, object action); int UnsubscribeByThisEmisor([CallerFilePath] string emisor = ""); int UnsubscribeAll(); }
Simple Send / Suscribe
void Send<TMessage>(string key, TMessage messageObject) void Subscribe<TMessage>(string key, Action<TMessage> action)
Is the simplest case. Sender and subscriber are connected by a simple key
.
Transmitter send an empty message and receiver does a configured job when receive empty message. It is an empty notice message.
For our example, we will a message to open a new window
(about window) from a button
.
We will add a new View (About window) in our project.
We will add a new button
in MainWindow.xaml
.
Xaml MainWindow new code:
<Button Command="{Binding AboutCommand}" Style="{StaticResource SimpleButton}" Content="About" Height="20" Width="50" Margin="40,25,39,0" Background="LightBlue" > <Button.BitmapEffect> <DropShadowBitmapEffect/> </Button.BitmapEffect> </Button>
We will add the send message in SimpleRelayCommand
implementation Action
method in our MainViewModel.cs
.
using MoralesLarios.FluentMVVM.Messages;
public SimpleRelayCommand AboutCommand => new SimpleRelayCommand(AboutExecuted); private void AboutExecuted() { MessengerManager._.Send($"{nameof(MainViewModel)}-OpenAbout"); }
We will add suscrive code in view codebehind MainWindow.xaml.cs
.
using MoralesLarios.FluentMVVM.Messages;
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); MessengerManager._.Subscribe($"{nameof(MainViewModel)}-OpenAbout", OpenAboutAction); } private void OpenAboutAction() { new About().Show(); } }
All process in video.
Simple Send / Suscrive with callback action
public void Send<TCallback>(string key, Action<TCallback> callback); public void SubscribeWithCallback<TCallback>(string key, Action<Action<TCallback>> actionWithCallbackParameter);
It’s the same example but in this case, we will add a callback
action for the user response.
We will add a message confirmation for reset the filters.
We will Add a Command button
in xaml code:
<Button Command="{Binding ResetCommand}" Content="Reset" />
public SimpleRelayCommand ResetCommand => new SimpleRelayCommand(ResetCommandExecuted, () => ! string.IsNullOrEmpty(ViewBag.ArtistNameFilter) || ! string.IsNullOrEmpty(ViewBag.AlbumNameFilter)); private void ResetCommandExecuted() { MessengerManager._.Send<bool>($"{nameof(MainViewModel)}-ResetFilter", ResetFilterCallbak); } private void ResetFilterCallbak(bool response) { if (response) InitialViewBag(); }
Call MessengerManager Send bool
message in the ResetCommandExected command
method. We will configure ResetFilterCallback method
of Action bool type to receive the user’s response. If response in true, we will reset filters textboxex.
public MainWindow() { InitializeComponent(); MessengerManager._.SubscribeWithCallback<bool>($"{nameof(MainViewModel)}-ResetFilter", ResetFilterAction); } private void ResetFilterAction(Action<bool> callback) { var userResponse = MessageBox.Show($"Can you reset filters ?", "Reset Filters", MessageBoxButton.YesNo, MessageBoxImage.Information); var responseResult = userResponse == MessageBoxResult.Yes; callback(responseResult); }
We will subscribe in the View constructor
, with a special method SuscriveWithCallback bool
.
Notification response is a typical example for this method. We will store user’s response, and cast to bool this response to send it back to ViewModel
.
Screen Filtered.
Notification popup.
Send / Subscribe with Messenger Object
void Send<TMessage>(string key, TMessage messageObject) void Subscribe<TMessage>(string key, Action<TMessage> action)
Is the simplest case. Sender and subscriber are connected by a simple key
with a second parameter with extra information.
Transmitter send an empty message and receiver does a configured job when receive empty message. It is an empty notice message.
For our example, we will a personal message to our View
, and we will show this message in a MessageBox
. In this example, extra information is a string type
, but this will be another class.
We will send message personalized information for the close button. The confirmation will be left for the following example.
We will add a Command
to the close button
.
<Button Command="{Binding CloseCommand}" ToolTip="Close Screen" />
We will add a SimpleRelayCommand
, with an executed action, with a MessengerManager Send method
call, with a message information.
public SimpleRelayCommand CloseCommand => new SimpleRelayCommand(CloseExecuted); private void CloseExecuted() { MessengerManager._.Send($"{nameof(MainViewModel)}-Close", $"You are closing the app at {DateTime.Now}"); }
Finally, we will add View Code-behind
code, with a MessageBox
construction whit a message from the ViewModel
.
public MainWindow() { InitializeComponent(); MessengerManager._.Subscribe<string>($"{nameof(MainViewModel)}-Close", Closection); // more code } private void Closection(string obj) { MessageBox.Show(obj, "Close Window", MessageBoxButton.OK, MessageBoxImage.Information); Close(); }
Send / Subscribe with sender object and Simple Sender Callback Response
void Send<TMessage>(string key, TMessage messageObject, Action callback); void SubscribeWithCallback<TMessage>(string key, Action<TMessage, Action> actionWithCallbackParameter);
This case is the same to the last but adding a sender object to send. It is a little more complete. As we can see Send
and SubscribeWithCallback
methods are generics TMessage
type versions.
Transmitter send a message with a ‘data’ object and receiver does a configured job when receive message with extra info through ‘data’ object received. Inside of configured job, usually in the end we will execute delegate parameter callback
. It is an empty notice message. It is a notice message with extra info message with sender callback
.
We omitted the example, because are very similar to the above.
Send / Subscribe with sender object and Simple Sender Callback Response with response object
void Send<TMessage, TCallback>(string key, TMessage messageObject, Action<TCallback> callback); void SubscribeWithCallback<TMessage, TCallback>(string key, Action<TMessage, Action<TCallback>> actionWithCallbackParameter);
This case is the most complicated and the most completed. If we see methods signature we can see that they add two parameters type for method. The first designates the sender message object type and the second the sender response object type, at the same time, this parameters types they are part of Action
parameters types too.
Transmitter send a message with a ‘data’ object
and receiver does a configured job when receive message with extra info through ‘data’ object received
. Inside of configured job, usually in the end we will execute delegate parameter callback
adding its response object. It is a notice message with response object information. It is a notice message with extra info message with sender callback and response object.
We create a new internal type to save filter and actual time to send it to the View. We will call it FilterInfo.
public class FilterInfo { public string FilterName { get; set; } public string FilterAlbum { get; set; } public DateTime ActualTime { get; set; } }
Send ViewModel code.
public void Send_Suscribe_with_sender_object_and_simple_sender_Callback_Response_with_responseObject() { var filterInfo = new FilterInfo { FilterName = ViewBag.ArtistNameFilter, FilterAlbum = ViewBag.AlbumNameFilter, ActualTime = DateTime.Now }; MessengerManager._.Send<FilterInfo, bool>($"{nameof(MainViewModel)}-CaseComplexWithCallback", filterInfo, CaseComplexWithCallback); } private void CaseComplexWithCallback(bool response) { }
View code behind suscribe code.
public MainWindow() { InitializeComponent(); MessengerManager._.SubscribeWithCallback<FilterInfo, bool>($"{nameof(MainViewModel)}-CaseComplexWithCallback", CaseComplexWithCallbackAction); } private void CaseComplexWithCallbackAction(FilterInfo sendMessage, Action<bool> callback) { }
A typical example of this overload is MessageBox
show/response iteration,
Anonymous Methods
Anonymous methods are a simplified way of sending / receiving messages. They seek to save time by using anonymous types
, something similar to using objects in javascript.
This is one of the advantages of using Fluent MVVM, because it allows you to use cases for typed
(purist) and other anonymous / dynamic
classes for people who want more speed and simplicity of development.
In the last example, we have created a new type for send filter information. If we use anonymous methods
, we would have saved creating this class.
Send / Subscribe with Messenger Anonymous Object
void SendAnonymous(string key, object messageAnnonimous); void SubscribeAnonymous(string key, Action<dynamic> action);
These are the anonymous sender / subscribe messages. They have the same functionality than your brother’s generics, but made for vague like me. These methods aren’t for purists but accelerate development work since we don’t have to create a specific class
before only for transmission. As in another cases this has a cons that we lost the intellisense
.
Transmitter send a message with an anonymous ‘data’ object
and receiver does a configured job when receive message with extra info through ‘data’ object received. It is a notice message with extra info.
Remake the previous (simple format) example with anonymous method
.
Send ViewModel code.
public void Simple_Send_Anonymous() { var filterInfo = new { FilterName = ViewBag.ArtistNameFilter, FilterAlbum = ViewBag.AlbumNameFilter, ActualTime = DateTime.Now }; MessengerManager._.SendAnonymous($"{nameof(MainViewModel)}-SendSimpleAnonymous", filterInfo); }
Suscribe View Code-Behind method code.
public MainWindow() { MessengerManager._.SubscribeAnonymous($"{nameof(MainViewModel)}-SendSimpleAnonymous", SendSimpleAnonymousAction); } private void SendSimpleAnonymousAction(dynamic anonymousSendObject) { string filterName = anonymousSendObject.FilterName; string albumName = anonymousSendObject.FilterAlbum; DateTime sendTime = anonymousSendObject.ActualTime; // more code. }
Send / Subscribe with anonymous sender object and Simple Sender Callback Response with anonymous response object
void SubscribeAnonymous(string key, Action<dynamic> actionAnonymous); void SubscribeAnonymousWithCallback(string key, Action<dynamic, Action<dynamic>> actionWithCallbackAnonymous);
The same to last case, but adding an anonymous response object.
Transmitter send a message with an anonymous ‘data’ object
and receiver does a configured job when receive message with extra info through ‘data’ object received
. Inside of configured job, usually in the end we will execute delegate parameter callback
adding its response object. It is a notice message with response object information. It is a notice message with extra info message with sender callback
and response anonymous object
.
We omitted the example, because are very similar to the above.
The lost Suscribe optional parameters
In many previous signatures
, two optional parameters were missing for compression. These are the lost parameters:
[CallerFilePath] string emisor = "" bool isOverwrite = true
This is a real signature.
public void Subscribe<T>(string key, Action<T> action, [CallerFilePath] string emisor = "", bool isOverwrite = true);
To better understand the lost parameters utility, we must give a small service implementation description.
The Messenger engine
, save the subscriber for all Subscribe methods. This technique helps storage delegating its pseudo pk
in (key + subscriber) conjunction instead of the (key + Action reference). This helps for individuals subscribers unsubscribes.
Without having to save actions references in internal variables
are used for that Visual Studio auto-implementing methods
, and more importantly with this technique Messenger engine
can easily recognize subscriptions and overwrite them if they already exists so the user does not have to worry about unsubscribe his subscriptions on close/unload the window/class. All this is invisible for the user thought emisor (transmitter) parameter and CallerFilePath attribute
.
IsOverride
parameter allows throw exception
if override subscribe in messenger storage. This force to unsubscribe all subscriptions in all messenger class instantons. It isn’t necessary because the lost performance is priceless and unsubscribes work more tedious.
UnSuscribe Methods
Simple Unsubscribe
void Unsubscribe(string key);
Unsubscribe
all subscriptions subscribe with the key parameter
.
Unsubscribe for Action reference
void Unsubscribe(string key, object action);
Unsubscribe
all subscriptions subscribe with the key and action reference parameters
. It isn’t very practice method but can be useful when we save action reference in an internal method parameter.
Unsubscribe for actual transmitter
int UnsubscribeByThisEmisor([CallerFilePath] string emisor = "");
Unsubscribe
all subscriptions subscribe with the actual class. It is very useful for windows subscriptions, but it is only advisable for purist’s developments.
UnsubscribeAll
int UnsubscribeAll();
Clean all Messenger engine subscriptions.
Download Examples Code
Progressive slots put a number of the} wagered funds into a jackpot pool that progresses with each credit score bet. Individual slot machines can have a progressive jackpot or two or more slot machines additionally be} linked allowing many players to compete for 카지노사이트 a jackpot. The on line casino video games below have a number of the} most revolutionary options out there right now. Pair that with an excellent RTP, and it’s simple to see why they're fan-favorite real money slot video games.
ResponderEliminar