@@ -23,6 +23,54 @@ public delegate void MessageHandler<in TRecipient, in TMessage>(TRecipient recip
23
23
24
24
/// <summary>
25
25
/// An interface for a type providing the ability to exchange messages between different objects.
26
+ /// This can be useful to decouple different modules of an application without having to keep strong
27
+ /// references to types being referenced. It is also possible to send messages to specific channels, uniquely
28
+ /// identified by a token, and to have different messengers in different sections of an applications.
29
+ /// In order to use the <see cref="IMessenger"/> functionalities, first define a message type, like so:
30
+ /// <code>
31
+ /// public sealed class LoginCompletedMessage { }
32
+ /// </code>
33
+ /// Then, register your a recipient for this message:
34
+ /// <code>
35
+ /// Messenger.Default.Register<MyRecipientType, LoginCompletedMessage>(this, (r, m) =>
36
+ /// {
37
+ /// // Handle the message here...
38
+ /// });
39
+ /// </code>
40
+ /// The message handler here is a lambda expression taking two parameters: the recipient and the message.
41
+ /// This is done to avoid the allocations for the closures that would've been generated if the expression
42
+ /// had captured the current instance. The recipient type parameter is used so that the recipient can be
43
+ /// directly accessed within the handler without the need to manually perform type casts. This allows the
44
+ /// code to be less verbose and more reliable, as all the checks are done just at build time. If the handler
45
+ /// is defined within the same type as the recipient, it is also possible to directly access private members.
46
+ /// This allows the message handler to be a static method, which enables the C# compiler to perform a number
47
+ /// of additional memory optimizations (such as caching the delegate, avoiding unnecessary memory allocations).
48
+ /// Finally, send a message when needed, like so:
49
+ /// <code>
50
+ /// Messenger.Default.Send<LoginCompletedMessage>();
51
+ /// </code>
52
+ /// Additionally, the method group syntax can also be used to specify the message handler
53
+ /// to invoke when receiving a message, if a method with the right signature is available
54
+ /// in the current scope. This is helpful to keep the registration and handling logic separate.
55
+ /// Following up from the previous example, consider a class having this method:
56
+ /// <code>
57
+ /// private static void Receive(MyRecipientType recipient, LoginCompletedMessage message)
58
+ /// {
59
+ /// // Handle the message there
60
+ /// }
61
+ /// </code>
62
+ /// The registration can then be performed in a single line like so:
63
+ /// <code>
64
+ /// Messenger.Default.Register(this, Receive);
65
+ /// </code>
66
+ /// The C# compiler will automatically convert that expression to a <see cref="MessageHandler{TRecipient,TMessage}"/> instance
67
+ /// compatible with <see cref="MessengerExtensions.Register{TRecipient,TMessage}(IMessenger,TRecipient,MessageHandler{TRecipient,TMessage})"/>.
68
+ /// This will also work if multiple overloads of that method are available, each handling a different
69
+ /// message type: the C# compiler will automatically pick the right one for the current message type.
70
+ /// It is also possible to register message handlers explicitly using the <see cref="IRecipient{TMessage}"/> interface.
71
+ /// To do so, the recipient just needs to implement the interface and then call the
72
+ /// <see cref="MessengerExtensions.RegisterAll(IMessenger,object)"/> extension, which will automatically register
73
+ /// all the handlers that are declared by the recipient type. Registration for individual handlers is supported as well.
26
74
/// </summary>
27
75
public interface IMessenger
28
76
{
0 commit comments