IMessenger
接口
IMessenger
是工具包中的一个接口,规定了 Messenger 需要实现的一些方法,比如:
Register
:注册消息Unregister
:取消注册UnregisterAll
:取消所有注册Send
:发送消息
实现了这一接口的类
工具包中提供了两个实现了 IMessenger
接口的类:
WeakReferenceMessenger
:使用弱引用,避免内存泄漏StrongReferenceMessenger
:使用强引用,通常用于希望消息接收者不被 GC 回收的场景
一般来说,我们使用 WeakReferenceMessenger
即可。
基本用法
Messenger 的使用方法基本上分三步走:
- 声明一个消息类型,或使用工具包内置的几种类型
- 注册消息(
IMessneger.Register
) - 发送消息(
IMessenger.Send
)
下面是一个简单的例子:
class MessageSender
{
private readonly IMessenger _messenger;
public MessageSender(IMessenger messenger)
{
_messenger = messenger;
}
public void SendMessage()
{
// 发送消息
_messenger.Send(new MyMessage { Content = "Hello, world!" });
}
}
class MessageReceiver
{
private readonly IMessenger _messenger;
public MessageReceiver(IMessenger messenger)
{
_messenger = messenger;
// 注册指定类型的消息
_messenger.Register<MyMessage>(this, OnMessageReceived);
}
void OnMessageReceived(object recipient, MyMessage message)
{
Console.WriteLine($"Message received from {recipient.GetType().Name}: {message.Content}");
}
}
// 一个自定义消息类型
class MyMessage
{
public string Content { get; init; } = "";
}
Warning
每一个实例对于同一种消息,只能注册一次。如果多次使用 Register
方法进行注册,将会报错。对于这样的情况,可以使用 Unregister
方法取消注册,也可以使用 IsRegistered
方法判断是否已经注册。
这里的“同一种消息”除了消息本身的类型,还包括消息频道(Token
)。如果多次注册的消息种类相同,但是每次注册的频道不同,也是不会报错的。上述的两种方式都是支持选择消息频道的。
然后我们实例化这些类:
Program.cs
IMessenger messenger = WeakReferenceMessenger.Default;
var receiver = new MessageReceiver(messenger);
var sender = new MessageSender(messenger);
sender.SendMessage();
Note
这里我们使用了依赖注入的方式,将 IMessenger
注入到了 MessageSender
和 MessageReceiver
中。这样做的好处是,我们可以很方便地将 IMessenger
替换为其他实现了 IMessenger
接口的类,比如 StrongReferenceMessenger
;同时,在类中,我们也不需要关心 IMessenger
的具体实现,只需要知道它是一个 IMessenger
,以及它提供的方法即可。
运行即可看到效果:
Message received from MessageReceiver: Hello, world!
一些更复杂及灵活的用法详见后面的章节。