zoukankan      html  css  js  c++  java
  • 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消息通知实现机制详解(二)

        

      

  • 相关阅读:
    cookie记住密码功能
    jquery 实现邮箱输入自动提示功能
    忘记密码功能的安全实现(邮件方式)
    java 实现从15位~18位的身份证号码转换,校验中国大陆公民身份证、香港居民身份证、澳门身份证和台湾身份证。
    myeclipse中发送邮件出现Exception in thread "main" java.lang.NoClassDefFoundError: com/sun/mail/util/LineInputStream
    几种任务调度的 Java 实现方法与比较
    CentOs中mysql的安装与配置
    CentOs下jdk的安装
    linux中vi编辑器的使用
    Linux文件结构及基本文件夹
  • 原文地址:https://www.cnblogs.com/Khan-Sadas/p/10072012.html
Copyright © 2011-2022 走看看