简单写一个eventbus
前言
闲暇之余,简单写一个eventbus。
正文
什么是eventbus?
eventbus 是一个开源的发布订阅模式的框架,用于简化程序间不同组件的通信。
它允许不同组件间松耦合通信,组件之间不通过直接引用的方式,而是事件的方式进行消息传递。
下面进行代码演示:
首先是发布订阅,那么就应该有发布方法和订阅方法,因为是消息传递,那么就应该还有启动消费消息的方法。
public interface IEventBus : IDisposable
{
Task Publish<T>(T @event) where T : IntegrationEvent;
Task Subscribe<T>(IIntegrationEventHandler<T> handler)
where T : IntegrationEvent;
Task StartConsume();
}
大体我们要实现上面的功能。
然后我们可以定义事件的基础信息:
public class IntegrationEvent
{
public Guid Id { get; set; }
public DateTime OccurredOn { get; set; }
public IntegrationEvent()
{
Id = Guid.NewGuid();
OccurredOn = DateTime.Now;
}
}
比如说要有唯一的id,同时要有事件发生的时间。
订阅的话,那么需要指定处理的对象。
public interface IIntegrationEventHandler
{
}
public interface IIntegrationEventHandler<in TIntegrationEvent> :
IIntegrationEventHandler where TIntegrationEvent : IntegrationEvent
{
Task Handler(TIntegrationEvent @event);
}
处理对象设计也很简单,就是需要创建一个有能够处理IntegrationEvent的对象即可。
这里很多人会疑惑,为什么很多框架的泛型接口类,往往会创建一个非泛型的接口。
这个其实是为了进一步抽象,方便做集合处理,下面将会介绍到。
然后就可以写一个内存型的eventbus。
public class InMemoryEventBus : IDisposable
{
private Dictionary<string, List<IIntegrationEventHandler>>
_dictionary = new Dictionary<string, List<IIntegrationEventHandler>>();
public async Task Publish<T>(T @event) where T : IntegrationEvent
{
var fullName = @event.GetType().FullName;
if (fullName == null)
{
return;
}
var handlers = _dictionary[fullName];
foreach (var integrationEventHandler in handlers)
{
if (integrationEventHandler is IIntegrationEventHandler<T> handler)
{
await handler.Handler(@event);
}
}
}
public async Task Subscribe<T>(IIntegrationEventHandler<T> handler)
where T : IntegrationEvent
{
var fullname = typeof(T).FullName;
if (fullname == null)
{
return;
}
if (_dictionary.ContainsKey(fullname))
{
var handlers = _dictionary[fullname];
handlers.Add(handler);
}
else
{
_dictionary.Add(fullname, new List<IIntegrationEventHandler>()
{
handler
});
}
}
public void Dispose()
{
// 移除相关连接等
}
}
里面实现了eventbus的基本功能。可以看到上面的_dictionary,里面就是IIntegrationEventHandler,
所以泛型接口会继承一个非泛型的接口,是为了进一步抽象声明,对一些集合处理是很方便的。
然后这里为什么没有直接继承Ieventbus呢? 而是实现eventbus的功能。
因为Ieventbus 其实是面向用户的,继承ieventbus只是一个门面,相当于适配器。
而InMemoryEventBus 是为了实现功能。
可以理解为InMemoryEventBus 是我们电脑主板、cpu等,然后我们只需要一个实现其接口的组件,从而和外部连接。
而不是整个内核系统和外部直连,那么我们可以使用InMemoryEventBusClient 作为这个组件。
public class InMemoryEventBusClient : IEventBus
{
private readonly InMemoryEventBus _eventBus;
public InMemoryEventBusClient()
{
_eventBus = new InMemoryEventBus();
}
public void Dispose()
{
_eventBus.Dispose();
}
public async Task Publish<T>(T @event) where T : IntegrationEvent
{
await _eventBus.Publish(@event);
}
public async Task Subscribe<T>(IIntegrationEventHandler<T> handler) where T : IntegrationEvent
{
await _eventBus.Subscribe(@handler);
}
public Task StartConsume()
{
// 运行相关的消费
return Task.CompletedTask;
}
}
InMemoryEventBusClient 负责实现外部接口,InMemoryEventBus 负责实现功能。
从而达到解耦的目的。
同样的例子还有polly,这个框架应该很出名了,其中他里面就有很多衍生的组件,都是调用内核来适配其他框架定义的接口。
上面可以看到StartConsume什么都没有做,其功能被Publish给融合了。
只要publish就消费了。
如果我们扩展kafka的话,那么consume其实就是拉取数据然后消费,publish其实就是推向kafka,中间就是序列号和反序列话的过程。
结
eventbus 完善篇后续再补。
简单写一个eventbus的更多相关文章
- extjs开发———用extJS简单写一个饼状图
先上效果图: js编写部分简单如下,先插入一个模块,然后给模块中添加内容. var myChart1 = echarts.init(document.getElementById('myChart1' ...
- 用vue和layui简单写一个响应式数据展示表
在创建项目之前,先把我们需要的文件打包处理 <!DOCTYPE html> <html lang="en"> <head> <meta c ...
- 【转】用C写一个简单病毒
[摘要]在分析病毒机理的基础上,用C语言写了一个小病毒作为实例,用TURBOC2.0实现. [Abstract] This paper introduce the charateristic of t ...
- 用Python写一个简单的Web框架
一.概述 二.从demo_app开始 三.WSGI中的application 四.区分URL 五.重构 1.正则匹配URL 2.DRY 3.抽象出框架 六.参考 一.概述 在Python中,WSGI( ...
- 如何写一个简单的http服务器
最近几天用C++写了一个简单的HTTP服务器,作为学习网络编程和Linux环境编程的练手项目,这篇文章记录我在写一个HTTP服务器过程中遇到的问题和学习到的知识. 服务器的源代码放在Github. H ...
- 如何写一个简单的shell
如何写一个简单的shell 看完<UNIX环境高级编程>后我就一直想写一个简单的shell来作为练习,因为有事断断续续的写了好几个月,如今写了差不多来总结一下. 源代码放在了Github: ...
- 分享:计算机图形学期末作业!!利用WebGL的第三方库three.js写一个简单的网页版“我的世界小游戏”
这几天一直在忙着期末考试,所以一直没有更新我的博客,今天刚把我的期末作业完成了,心情澎湃,所以晚上不管怎么样,我也要写一篇博客纪念一下我上课都没有听,还是通过强大的度娘完成了我的作业的经历.(当然作业 ...
- 用qpython3写一个最简单的发送短信的程序
到目前为止并没有多少手机应用是用python开发的,不过qpython可以作为一个不错的玩具推荐给大家来玩. 写一个最简单的发送短信的程序,代码如下: #-*-coding:utf8;-*- #qpy ...
- 写一个ajax程序就是如此简单
写一个ajax程序就是如此简单 ajax介绍: 1:AJAX全称为Asynchronous JavaScript and XML(异步JavaScript和XML),指一种创建交互式网页应用的网页开发 ...
- 自己动手写一个简单的(IIS)小型服务器
因为第一次在博客园发表随笔,不太会用,这个笔记是我之前在印象笔记中写好的,然后直接copy过来,有兴趣自己做一个IIS服务器的小伙伴们可以参照下面的流程做一次,也可以叫我要源代码,不过要做完,我觉得花 ...
随机推荐
- mySQL清除数据表数据/删除表
一.sql清空表数据的三种方式: 1.truncate – 删除所有数据,保留表结构,不能撤销还原,速度快 2.delete – 是逐行删除,不适合大量数据删除,速度极慢 3.drop – 删除表,表 ...
- C++//queue 队列 容器 先进先出 只有队头 队尾能被外界访问 因此不允许有遍历行为
1 //queue 队列 容器 先进先出 只有队头 队尾能被外界访问 因此不允许有遍历行为 2 3 4 #include<iostream> 5 #include<queue> ...
- vscode复制相对路径时是反斜杠\,改为正斜杠/ [转]
痛点:复制路径的时候斜杠不对 解决:explorer.copyRelativePathSeparator 设置 在跳出来的设置页面的搜索栏里输入explorer.copyRelativePathSep ...
- react build 后,打包后自动将index.html copy 404.html - create-react-app 创建的项目
起因:build上传gitee,启用路由需要404.html自动跳转 当前环境 create-react-app 搭建的架子 解决方案 由于默认的时候把build.js打包,无法查看,只好eject ...
- esp8266 I2C 实例解析及源码分析
一 前言 作为一个方案商兼芯片开发者,研究芯片和功能实现除了基本的工作需要,还有一层就是也变成了一种职业习惯.从芯片到方案,发现很多方案公司的人水平都比较堪忧,只会调用api,根本不会看底层的代码实 ...
- Java | zuul 1.x 是如何实现请求转发的
zuul 1.x 是如何实现请求转发的 文档写的再好,也不如源码写的好 源码地址: GitHub: https://github.com/Netflix/zuul Gitee: https://git ...
- python高级技术(网络编程二)
一 粘包现象(基于TCP协议实现远程执行命令) 1.TCP协议,会出现粘包现象 例:ipconfig命令,客户端收到的字符串比较短,客户端能够收完整, tasklist命令,客户端收到的字符串超过10 ...
- 初探修模的三维模型OBJ格式轻量化压缩的遇到常见问题与处理方法
初探修模的三维模型OBJ格式轻量化压缩的遇到常见问题与处理方法 在对经过修模的三维模型进行OBJ格式轻量化压缩处理的过程中,可能会遇到一些常见问题.以下是一些常见问题以及相应的处理方法: 1.顶点丢失 ...
- Cesium之CustomShader
1. 引言 Cesium自1.87.1版本,开始支持3DTileset使用CustomShader: Added CustomShader class for styling Cesium3DTile ...
- WPF状态保存
由于WPF做客户端的时候,它不像BS那样有Session,Cookie给你使用,所以保存状态你首先想到的就是数据库了. 但是你不可能什么都放在数据库,为此还专门为它建立一张表. 而WPF中能用到的除了 ...