• EventBus总线讲解


           在我们公司经常用到总线,具体的总线是什么让我理解我也不清楚,但是在这几个月下来,我已经知道总线如何使用,现在加上示例讲解总线如何使用。

    1. 首先我们的新建一个类,这个类其实是用于总线传递的模型

       

    using System;

    namespace PurchaseDevices.Model.CommonModel
    {
    /// <summary>
    /// 事件传递参数
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class FlowDataEventArgs<T> : EventArgs
    {
    public FlowDataEventArgs(T data)
    {
    Data = data;
    }
    public T Data { get; set; }
    }
    }

    2. 建立一个类(FlowServiceBus),里面来写总线的方法。

      public class FlowServiceBus

    {
       static FlowServiceBus _flowServiceBus;

    public static FlowServiceBus Instance
    {
    get
    {
    if (_flowServiceBus == null) _flowServiceBus = new FlowServiceBus();
    return _flowServiceBus;
    }
    }

    }

    4. 写一个方法,里面挂总线

      public class FlowServiceBus

    {
       static FlowServiceBus _flowServiceBus;

    public static FlowServiceBus Instance
    {
    get
    {
    if (_flowServiceBus == null) _flowServiceBus = new FlowServiceBus();
    return _flowServiceBus;
    }
    }

     public void ConfigMsgDispachRule(){

       //挂总线

    }

    }

    5. 先讲一讲我们传统的调用另一个类的方法

    //新建一个对象模型类

    public class FarmerCardOrRateSellModel
    {
    public FarmerCardOrRateSellModel()
    {
    PackageHead = 0xAA;
    FixedLength = 11;
    }

    /// <summary>
    /// 帧头
    /// 帧开始标记,0xAA
    /// </summary>
    public byte PackageHead { get; set; }
    /// <summary>
    /// 接收者,标识数据要发给谁
    /// 1磅码主机、2定级键盘、3交烟刷卡。
    /// </summary>
    public byte Receiver { get; set; }
    /// <summary>
    /// 发送者,标识数据是谁发出
    /// 1磅码主机、2定级键盘、3交烟刷卡。
    /// </summary>
    public byte Sender { get; set; }
    /// <summary>
    /// Zigbee通信地址
    /// 1~15
    /// </summary>
    public byte ZigbeeAddress { get; set; }
    /// <summary>
    /// 帧序号
    /// 0~255
    /// </summary>
    public byte FrameNumber { get; set; }
    /// <summary>
    /// 命令码
    /// </summary>
    public byte Command { get; set; }
    /// <summary>
    /// 数据区字节数
    /// 
    /// </summary>
    public int DataLength { get; set; }
    /// <summary>
    /// 数据区,可无(数据区为0)
    /// </summary>
    public byte[] Data { get; set; }
    /// <summary>
    /// 从receiver到整个data的和校验
    /// </summary>
    public byte Crc { get; set; }
    /// <summary>
    /// 定长 除开数据区的长度 定长为11
    /// </summary>
    public int FixedLength { get; set; }

    }

    //我们现在要做的是  根据不同的发送者Sender  ,进入不同的方法

    private void DisSenderToDisWay(FarmerCardOrRateSellModel farmerCardOrRateSellModel)
    {
    DevTypeEnum devTypeEnum = (DevTypeEnum)farmerCardOrRateSellModel.Sender;  //这里是一个枚举,这里就不详细讲解了,这里就是说                                                                                                                                                           //Sender有不同的值
    switch (devTypeEnum)
    {

    case DevTypeEnum.CardDev:
        CardDev cardDev=new CardDev ();

       cardDev.CardDevWay(farmerCardOrRateSellModel);

    break;
    case DevTypeEnum.LevelDev:

    LevelDev levelDev=new LevelDev();

    levelDev.LevelDevWay(farmerCardOrRateSellModel);

    break;
    default:
    Logger.GetInstance().Warn("无法识别的发送者");
    break;
    }
    }

    //当sender为CardDev要执行的方法

    public class  CardDev{

        public  void   CardDevWay(FarmerCardOrRateSellModel farmerCardOrRateSellModel){

    //执行的方法

    }

    }

    //当sender为LevelDev要执行的方法

    public class  LevelDev{

        public  void   LevelDevWay(FarmerCardOrRateSellModel farmerCardOrRateSellModel){

    //执行的方法

    }

    }

    }

    在传统的方法中 ,一个类要引用另一个类的方法,我们必须new 一个对象,然后引用方法。这样写没有错,我以前也是这样写的,对于一些不复杂程序中的我么可以这样写,但是在一些与设备交互的程序中,多半是总线将各个方法连接起来,我们不必关心谁是发送者,谁是接收者,每个方法只关心我拿到这个传递过来的值,该干什么,我也不必关心我应该把这个方法的结果发给谁用。这样低耦合。

      

       现在我们来讲讲用总线的方法,应该怎么写:

       还是保留FarmerCardOrRateSellModel类。

    下面这个方法 我们用事件来写:

    写事件:

    public event EventHandler<FlowDataEventArgs<FarmerCardOrRateSellModel>> OnReceiveCardDataEventHadler;

      public event EventHandler<FlowDataEventArgs<FarmerCardOrRateSellModel>> OnReceiveLevelDataEventHadler;

    private void DisSenderToDisWay(FarmerCardOrRateSellModel farmerCardOrRateSellModel)
    {
    DevTypeEnum devTypeEnum = (DevTypeEnum)farmerCardOrRateSellModel.Sender;  
    switch (devTypeEnum)
    {

    case DevTypeEnum.CardDev:

    if (OnReceiveCardDataEventHadler!=null)
    {
    OnReceiveCardDataEventHadler(this,new FlowDataEventArgs<FarmerCardOrRateSellModel>(farmerCardOrRateSellModel));
    }

    break;
    case DevTypeEnum.LevelDev:

    if (OnReceiveLevelDataEventHadler!=null)
    {
    OnReceiveLevelDataEventHadler(this, new FlowDataEventArgs<FarmerCardOrRateSellModel>(farmerCardOrRateSellModel));

    }

    break;
    default:
    Logger.GetInstance().Warn("无法识别的发送者");
    break;
    }
    }

    //我们要写两个方法  ,这两个方法就是Sender为LevelDev 和CardDev,他们拿到数据自己需要怎么处理的方法了

    //当sender为CardDev要执行的方法

    public class  CardDev{

        public  void   CardDevWay(object sender, FlowDataEventArgs<FarmerCardOrRateSellModel> e){

         var data=e.Data;  //data就为传送过来的FarmerCardOrRateSellModel对象

    }

    }  

    //当sender为LevelDev 要执行的方法

    public class  LevelDev{

        public  void   LevelDevWay(object sender, FlowDataEventArgs<FarmerCardOrRateSellModel> e){

        var data=e.Data;  //data就为传送过来的FarmerCardOrRateSellModel对象

    }

    }

    //写到这里 我们已经把各自内部的方法完成了,现在我们要完成的就是 ,如何将方法与方法直接串联起来,怎么让sender为CardDev时就进入对应的CardDevWay方法南。那么现在就是要挂总线了。

    还记的我们在总线类里面写的方法么:

    现在我们要在里面添加一些代码了。

      public class FlowServiceBus

    {
       static FlowServiceBus _flowServiceBus;

    public static FlowServiceBus Instance
    {
    get
    {
    if (_flowServiceBus == null) _flowServiceBus = new FlowServiceBus();
    return _flowServiceBus;
    }
    }

    //新建对象

      private  readonly  DisSenderToDisWay  _disSenderToDisWay=new DisSenderToDisWay();

      private  readonly  CardDev _cardDev=new CardDev ();

      private  readonly  LevelDev _levelDev=new LevelDev ();

     public void ConfigMsgDispachRule(){

      EventBroker eventBroker =new EventBroker();

    eventBroker.SpecialCasesRegistrar.AddPublication("发送者为CardDev 的方法", _disSenderToDisWay,
    "OnReceiveCardDataEventHadler", HandlerRestriction.None);

    eventBroker.SpecialCasesRegistrar.AddSubscription<FlowDataEventArgs<FarmerCardOrRateSellModel>>("发送者为CardDev 的方法",
    _cardDev, _cardDev.CardDevWay, new OnPublisher());

    //这是一组对应的  可以这样理解 :当执行到DisSenderToDisWay 类里面的OnReceiveCardDataEventHadler事件时,就执行CardDev 里面的CardDevWay方法

    //按照以上的里面  当我们执行DisSenderToDisWay 类里面的OnReceiveLevelDataEventHadler事件时,接下来我们应该执行LevelDev类里面的LevelDevWay方法南

    eventBroker.SpecialCasesRegistrar.AddPublication("发送者为LevelDev  的方法", _disSenderToDisWay,
    "OnReceiveLevelDataEventHadler", HandlerRestriction.None);
    eventBroker.SpecialCasesRegistrar.AddSubscription<FlowDataEventArgs<FarmerCardOrRateSellModel>>("发送者为LevelDev 的方法",
    _levelDev, _levelDev.LevelDevWay, new OnPublisher());

    }

    }

    总线这个要慢慢理解,刚开始我也不知道如何将两个方法挂接起来的,慢慢的理解就行了。在平常代码中我们很少使用总线,但是对于有些公司可能还是经常会用到的,对于那些刚刚接触到总线的朋友们,希望对你们初步理解与简单使用有帮助。

  • 相关阅读:
    linux nat style
    vmware tools install
    linux network
    sql group by max
    实例 | tp5使用七牛云上传图片和文件/删除文件
    菜鸟如何使用composer
    浅谈数据库用户表结构设计,第三方登录
    app登陆,注册,第三方登陆数据设计及业务流程
    数据库设计——评论回复功能
    app接口设计之token的php实现
  • 原文地址:https://www.cnblogs.com/yaoxiaodan/p/6249688.html
Copyright © 2020-2023  润新知