EventBus实现 - 发布订阅 - XML加载
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科技,服务社会。
EventBus实现 - 发布订阅 - XML加载的更多相关文章
- 实战android菜单项之XML加载菜单与动态菜单项[转]
原文地址:http://blog.csdn.net/kaiwii/article/details/7767225 自定义android应用程序的菜单项首先要知道切入点.经过学习,知道主要是两个Acti ...
- JAVA Web.xml 加载顺序
web.xml加载过程(步骤): 1.启动WEB项目的时候,容器(如:Tomcat)会去读它的配置文件web.xml.读两个节点: <listener></listener> ...
- Java web.xml加载顺序
web.xml加载过程(步骤): 1.启动WEB项目的时候,容器(如:Tomcat)会去读它的配置文件web.xml.读两个节点: <listener></listener&g ...
- web.xml加载过程
web.xml加载过程:1 启动WEB项目的时候,容器(如:Tomcat)会读他的配置文件web.xml读两个节点 <listener></listener>和<con ...
- 想要配置文件生效 需要通过添加到web.xml加载到内存中
想要配置文件生效 需要通过添加到web.xml加载到内存中
- 使用EventBus + Redis发布订阅模式提升业务执行性能
前言 最近一直奔波于面试,面了几家公司的研发.有让我受益颇多的面试经验,也有让我感觉浪费时间的面试经历~因为疫情原因,最近宅在家里也没事,就想着使用Redis配合事件总线去实现下具体的业务. 需求 一 ...
- web.xml加载顺序
一 1.启动一个WEB项目的时候,WEB容器会去读取它的配置文件web.xml,读取<listener>和<context-param>两个结点. 2.紧急着,容创建一个Ser ...
- WEB容器启动——web.xml加载详解
最近在看spring的源码,关于web.xml文件在容器(Tomcat.JBOSS等)启动时加载顺序问题很混乱,通过搜集资料,得出以下的结论: 1.加载顺序与它们在 web.xml 文件中的先后顺序无 ...
- maven pom.xml加载不同properties配置[转]
可以参考http://www.openwebx.org/docs/autoconfig.html 1.pom.xml =========================== <!-- 不同的打包 ...
随机推荐
- android 卸载程序、清除数据、停止服务用法
要实现卸载程序.清除数据.停止正在执行的服务这几大模块,如今将代码粗略总结例如以下: 主要运用到的类有 PackageManager ActivityManager ApplicationInfo R ...
- Mediator - 中介者模式
定义 用一个中介对象来封装一系列的对象的交互.中介者使各对象不须要显示地相互使用,从而使其耦合松散,并且能够独立的改变他们之间的交互. 案例 比方有一个图像界面,在界面上有一个输入框LineEdit, ...
- Fluent Validation + NInject3 + MVC5
Fluent Validation + NInject + MVC - Why & How : Part 1 http://fluentvalidation.codeplex.com/ htt ...
- WebService使用JSON格式传递笔记+JQuery测试
原文WebService使用JSON格式传递笔记+JQuery测试 因为一些因素,必须改写WebService,很传统,但是很多公司还在用.. 因为XML 的关系,不想让他传递数据的时候过度肥大,所以 ...
- each与list的用法
each与list的用法(PHP学习) 1.each的用法 先看API array each ( array &$array ) api里是这么描述的:each — 返回数组中当前的键/值对并 ...
- 基于4.5Framework web程序、SQLSERVER数据库打包
原文:基于4.5Framework web程序.SQLSERVER数据库打包 估计很多朋友和我一样,对于C/S程序打包很熟悉,但对于B/S程序打包一头雾水... 最近公司要求我们把项目和数据库(SQL ...
- 【COCOS2DX-游戏开发之三四】cocos2dx 3.0 TableView特殊使用方法:滚动时不能选择等等
cocos2dx 3.0版本号TableView拍生自ScrollView,经常使用来做滚动列表,有几种特殊使用方法,不知道大家用到过没 要求:1.滚动时不能选中TableCell,非滚动状态才干选中 ...
- selenium2入门 用selenium安装、加载、启用插件(一)
一:下载 下载地址是:http://docs.seleniumhq.org/download/
- 读书笔记—CLR via C#委托和attribute
前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...
- 读书笔记—CLR via C#章节1-2
这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可以加深 ...