zoukankan      html  css  js  c++  java
  • EventBus实现

    EventBus实现 - 发布订阅 - XML加载

    受到CQRS的影响,写了个EventBus,能实现发布订阅模式执行event,在DDD模型中,可以使用如下代码触发事件:

    EventBus bus = EventBus.Instance();
    bus.Publish(new OrderAddedEvent());

     解决方案结构图如下,很简单易懂:

     xml事件配置代码sample如下(1个event可以定义多个订阅者,如下):

    复制代码
    <?xml version="1.0" encoding="utf-8" ?>
    <Events>
      <Event>
        <PublishEvent>ConsoleApplication2.code.Events.OrderAddedEvent</PublishEvent>
        <SubscribedEvents>
          <SubscribedEvent>ConsoleApplication2.code.EventHandlers.OrderAddedEventHandler_CachePrepare</SubscribedEvent>
            <SubscribedEvent>ConsoleApplication2.code.EventHandlers.OrderAddedEventHandler_PDFGenerate</SubscribedEvent>
        </SubscribedEvents>
      </Event>
      <Event>
        <PublishEvent>ConsoleApplication2.code.Events.OrderDeletedEvent</PublishEvent>
        <SubscribedEvents>
          <SubscribedEvent>ConsoleApplication2.code.EventHandlers.OrderDeletedEventHandler_NotifyClient</SubscribedEvent>
          <SubscribedEvent>ConsoleApplication2.code.EventHandlers.OrderDeletedEventHandler_RemovCache</SubscribedEvent>
        </SubscribedEvents>
      </Event>
    </Events>
    复制代码

     我们先来定义Event:

    复制代码
    public class BaseEvent         //空的,不需要实现其他方法
    {
    }
    public class OrderAddedEvent : BaseEvent      //订单已经加入,触发的event
    {
    }
    public class OrderDeletedEvent : BaseEvent     //订单已经删除,触发的event
    {
            public Guid OrderId { get; set; }
            public OrderDeletedEvent(Guid orderId)
            {
                this.OrderId = orderId;
            }
    }
    复制代码

     定义事件的处理程序:

    复制代码
    public interface IEventHandler<T>
            where T : BaseEvent
    {
            void Handle(T evt);
    }
    public class OrderDeletedEventHandler_NotifyClient : IEventHandler<OrderDeletedEvent>
    {
            public void Handle(OrderDeletedEvent evt)
            {
                Console.WriteLine("[Order deleted] Notified.");
            }
    }
    复制代码

    上面2个步骤很简单,只是简单的定义事件、事件处理程序,要怎样才能触发事件处理程序并且做成可配置的方式呢?请看下面代码即可:

    复制代码
    private static Dictionary<Type, List<Type>> eventMapping = new Dictionary<Type, List<Type>>();
    
    XElement root=XElement.Load(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "EventBus.xml"));  //这个xml文件需要设置为一直拷贝到程序目录中
    foreach (var evt in root.Elements("Event"))
    {
           List<Type> eventHandlers = new List<Type>();
    
           Type publishEventType = Type.GetType(evt.Element("PublishEvent").Value);
           foreach (var subscritedEvt in evt.Elements("SubscribedEvents"))
                foreach (var concreteEvt in subscritedEvt.Elements("SubscribedEvent"))
                    eventHandlers.Add(Type.GetType(concreteEvt.Value));
    
           eventMapping[publishEventType] = eventHandlers; //加入Dictionary中
    }
    复制代码

    再来上发布代码:

    复制代码
            public void Publish(BaseEvent evt)
            {
                var result = from tb in eventMapping
                             where tb.Key.Equals(evt.GetType())
                             select tb;
    
                foreach (KeyValuePair<Type, List<Type>> t in result.ToList())
                {
                    foreach (Type tt in t.Value)
                    {
                        Type targetType = tt;
                        MethodInfo mi=targetType.GetMethod("Handle"); //这个Handle文本字符串,必须和IEventHandler<T>中定义的方法一致
                        if(mi==null)
                            continue;
    
                        object o = Activator.CreateInstance(targetType);  //new实例
                        mi.Invoke(o, new object[] { evt });               //调用方法,并且传入事件参数
                    }
                }
            }
    复制代码

    运行效果图如下:

    代码下载

    自省推动进步,视野决定未来。
    心怀远大理想。
    为了家庭幸福而努力。
    用A2D科技,服务社会。
     
    分类: 架构可扩展
  • 相关阅读:
    ZOJ 2158 Truck History
    Knight Moves (zoj 1091 poj2243)BFS
    poj 1270 Following Orders
    poj 2935 Basic Wall Maze (BFS)
    Holedox Moving (zoj 1361 poj 1324)bfs
    ZOJ 1083 Frame Stacking
    zoj 2193 Window Pains
    hdu1412{A} + {B}
    hdu2031进制转换
    openjudge最长单词
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3222308.html
Copyright © 2011-2022 走看看