简单写一个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服务器的小伙伴们可以参照下面的流程做一次,也可以叫我要源代码,不过要做完,我觉得花 ...
随机推荐
- C++ //string字符串拼接
1 //string字符串拼接 2 #include <iostream> 3 #include<string> 4 5 using namespace std; 6 7 8 ...
- 数据安全刻不容缓,国产智能化厂商首获SOC 2鉴证报告有何意义?
数据安全刻不容缓,国产智能化厂商首获SOC 2鉴证报告有何意义? 了解SOC 2与ISO 27001的区别,你就知道SOC 2对智能自动化厂商的意义了 文/王吉伟 要问当前组织对于数字化转型的最大顾虑 ...
- liunx 安装 python 虚拟环境, 各种方法,
liunx 安装 python 虚拟环境,主要是要解决工作中需要用到python3.6,但是系统的2.7又不能动,安装系统组件时避免造成冲突.低版本的python安装django uwsgi 等都用 ...
- 使用 Abp.Zero 搭建第三方登录模块(二):服务端开发
微信SDK库的集成 微信SDK库是针对微信相关 API 进行封装的模块 ,目前开源社区中微信SDK库数量真是太多了,我选了一个比较好用的EasyAbp WeChat库. EasyAbp/Abp.W ...
- 基于六轴传感器MPU6050的物体移动监测报警系统
一 系统简介 1.简介 MPU-60x0 是全球首例 9 轴运动处理传感器.它集成了 3 轴MEMS陀螺仪,3 轴MEMS加速度计,以及一个可扩展的数字运动处理器 DMP(Digital Motion ...
- ESP8266 SPI 开发之软硬基础分析
一 什么是SPI接口? SPI是一种高速.高效率的串行接口技术.通常由一个主模块和一个或多个从模块组成,主模块选择一个从模块进行同步通信,从而完成数据的交换.SPI是一个环形结构,通信时需要至少4根线 ...
- Oss流程分析
最新式上传方案是:前端上传获取token,然后token中带有bucket.账号.回调地址等相关信息,前端直接上传到阿里云,阿里云上传成功后回调之前设定好的地址,完成上传.(下图是技术负责人的图,盗来 ...
- FAT32 文件系统详解
PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明 本文作为本人csdn blog的主站的备份.(Bl ...
- Welcome to YARP - 2.2 配置功能 - 配置提供者(Configuration Providers)
目录 Welcome to YARP - 1.认识YARP并搭建反向代理服务 Welcome to YARP - 2.配置功能 2.1 - 配置文件(Configuration Files) 2.2 ...
- AES算法:加密通信的新选择
AES算法起源: AES(Advanced Encryption Standard)算法是一种对称密钥加密算法,由比利时密码学家Joan Daemen和Vincent Rijmen设计,于2001年被 ...