MVVMLight消息通知实现机制详解(一)

  最近对委托、事件的订阅使用的太多,订阅与被订阅之间的绑定约束非常...麻烦,所以翻了下MVVMLight源码找出这段可以拿出来用的部分,详情见下:

  一.开发中遇到的问题:

  场景1:ClassA中存在事件OnDataChanged,在数据发生改变时调用OnDataChanged事件通知其订阅者ClassB做相应处理

  1. 实现过程一般分如下几种
  • ClassB中有ClassA的实例,然后订阅事件
  • ClassA是单例模式,可以直接在ClassB中订阅单例ClassA的实例事件
  • ClassA、ClassB的实例在一个共同的对象中,ClassB订阅ClassA的实例事件

  问题:发生订阅这件事儿永远都需要前提条件,订阅方与被订阅方必须直接接触到才可以实现该逻辑,这样在不需要订阅与被订阅的对象接触时就不好处理逻辑了

  场景2:A、B两个人合作,分别写订阅方逻辑、被订阅方逻辑

  实现过程中,会遇到如下问题:

  • B需要依赖A必须先写好订阅事件才可以开始自己的工作
  • 在A、B双方对事件的参数、命名等发生修改时必须及时通知对方并要求对方立即更正,否则无法实现编译、调试和运行

  

  二.MVVMLight中消息通知机制的对外实现

  • 框架下对所有对象提供单例Messenger工具类,任何需要订阅、被订阅(发送、接收事件消息)的对象都通过对Messenger进行调用实现
  • 避免了订阅方与被订阅方必须实例接触的问题了
  • 调用方式上,在发送和接收用如下参数定义方式实现
/// <summary>
/// 注册订阅事件
/// </summary>
/// <typeparam name="TMessage">传参类型</typeparam>
/// <param name="recipient">订阅实例</param>
/// <param name="token">发送与接收定义的key值</param>
/// <param name="action">订阅事件触发的action</param>
/// <param name="keepTargetAlive">持续控制实例存在,防止被回收清除</param>
public virtual void Register<TMessage>(object recipient,object token,Action<TMessage> action,bool keepTargetAlive = false)
/// <summary>
/// 被订阅方触发事件
/// </summary>
/// <typeparam name="TMessage">传参类型</typeparam>
/// <param name="message">参数数据</param>
/// <param name="token">key</param>
public virtual void Send<TMessage>(TMessage message, object token)

  例

public class Class1
{
public Class1()
{
MessageTool.Messenger.Default.Register<string>(this, "key", DataChangedHandle);
} //订阅触发事件
public void DataChangedHandle(string obj)
{
//dosomething
} /// <summary>
///对外通知事件消息
/// </summary>
public void SendMessage() {
MessageTool.Messenger.Default.Send("Message", "key");
}
}

  逻辑解释:

  • 订阅时传参的“Key”是发送与接收之间唯一的key值,它的类型是object类型,也就是说可以根据自身需求进行设置key值类型
  • Messenger其内部逻辑是在对Key值和传参类型进行比对,完全符合时才会调用订阅方实例的action
  • Messenger有多重重载,订阅时不设置key,对任何传参类型相同的调用都接收触发,详情找机会下次分享

  优点:避免订阅与被订阅的实例接触、事件参数命名发生改变时影响变小,最多触发不到,不会影响编译

   缺点:我看到的必须有传参,即使null也可以,但必须有

  

  下一节对这段源码拿出来看下什么情况,挖坑待填

  

  接上文:

MVVMLight消息通知实现机制详解(二)

    

  

上一篇:MVVMLight消息通知实现机制详解(二)


下一篇:Orcale 数据库客户端PL/SQL中文乱码的问题