前言

闲暇之余,简单写一个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的更多相关文章

  1. extjs开发———用extJS简单写一个饼状图

    先上效果图: js编写部分简单如下,先插入一个模块,然后给模块中添加内容. var myChart1 = echarts.init(document.getElementById('myChart1' ...

  2. 用vue和layui简单写一个响应式数据展示表

    在创建项目之前,先把我们需要的文件打包处理 <!DOCTYPE html> <html lang="en"> <head> <meta c ...

  3. 【转】用C写一个简单病毒

    [摘要]在分析病毒机理的基础上,用C语言写了一个小病毒作为实例,用TURBOC2.0实现. [Abstract] This paper introduce the charateristic of t ...

  4. 用Python写一个简单的Web框架

    一.概述 二.从demo_app开始 三.WSGI中的application 四.区分URL 五.重构 1.正则匹配URL 2.DRY 3.抽象出框架 六.参考 一.概述 在Python中,WSGI( ...

  5. 如何写一个简单的http服务器

    最近几天用C++写了一个简单的HTTP服务器,作为学习网络编程和Linux环境编程的练手项目,这篇文章记录我在写一个HTTP服务器过程中遇到的问题和学习到的知识. 服务器的源代码放在Github. H ...

  6. 如何写一个简单的shell

    如何写一个简单的shell 看完<UNIX环境高级编程>后我就一直想写一个简单的shell来作为练习,因为有事断断续续的写了好几个月,如今写了差不多来总结一下. 源代码放在了Github: ...

  7. 分享:计算机图形学期末作业!!利用WebGL的第三方库three.js写一个简单的网页版“我的世界小游戏”

    这几天一直在忙着期末考试,所以一直没有更新我的博客,今天刚把我的期末作业完成了,心情澎湃,所以晚上不管怎么样,我也要写一篇博客纪念一下我上课都没有听,还是通过强大的度娘完成了我的作业的经历.(当然作业 ...

  8. 用qpython3写一个最简单的发送短信的程序

    到目前为止并没有多少手机应用是用python开发的,不过qpython可以作为一个不错的玩具推荐给大家来玩. 写一个最简单的发送短信的程序,代码如下: #-*-coding:utf8;-*- #qpy ...

  9. 写一个ajax程序就是如此简单

    写一个ajax程序就是如此简单 ajax介绍: 1:AJAX全称为Asynchronous JavaScript and XML(异步JavaScript和XML),指一种创建交互式网页应用的网页开发 ...

  10. 自己动手写一个简单的(IIS)小型服务器

    因为第一次在博客园发表随笔,不太会用,这个笔记是我之前在印象笔记中写好的,然后直接copy过来,有兴趣自己做一个IIS服务器的小伙伴们可以参照下面的流程做一次,也可以叫我要源代码,不过要做完,我觉得花 ...

随机推荐

  1. 【专业技能】程序员的软件工程素养之画好 UML 时序图

    目录 前言 一.认识时序图 1.1时序图元素 1.2怎么使用 二.画好时序图 2.1一般步骤 2.2举个例子 2.3推荐工具 三.其它作用 四.文章小结 前言 笔者在本科的时候上过软件工程的专业课,也 ...

  2. RocketMQ(10) 消息类型

    一.普通消息 1. 消息发送方式分类 Producer对于消息的发送方式也有多种选择,不同的方式会产生不同的系统效果. 同步发送消息: 同步发送消息是指,Producer发出⼀条消息后,会在收到MQ返 ...

  3. FeignClient 报错: A bean with that name has already been defined and overriding is disabled.

    1. 错误信息 *************************** APPLICATION FAILED TO START *************************** Descript ...

  4. JVM解析

    synize锁升级

  5. WPF --- 重写圆角DataGrid样式

    引言 因要符合UI设计, 需要一个圆角的 DataGrid 样式,其需要一个,所以需要重写DataGrid的样式, 代码 具体样式代码如下: <ResourceDictionary xmlns= ...

  6. 记一次docker安装Jenkins

    docker安装Jenkins 0. 下载docker镜像 docker search jenkins docker pull jenkins/jenkins:lts 1. 安装步骤 创建映射文件夹 ...

  7. Android 语音播放(文字TTS)

    原文地址:Android 语音播放(文字TTS) | Stars-One的杂货小窝 基于Google内置的TTS引擎,封装了个语音播放的工具类 使用 //初始化 SpeechService.init( ...

  8. MediaBox音视频终端SDK已适配鸿蒙星河版(HarmonyOS NEXT)

    2024年1月,HarmonyOS NEXT 鸿蒙星河版系统开发者预览版开放申请,该系统将只能安装为鸿蒙开发的原生应用,而不再兼容安卓应用.对此,阿里云MediaBox音视频终端SDK产品已实现功能的 ...

  9. opencv-python笔记(1)

    openCV笔记 图像 灰度图像 ​ 0代表纯黑色,255代表白色(类似亮度) 通道拆分 通过索引拆分: import cv2 lena=cv2.imread("lenacolor.png& ...

  10. 引领汽车营销新趋势,3DCAT实时云渲染助力汽车三维可视化

    当前,汽车产业发展正从电动化的上半场,向智能化的下半场迈进.除了车机技术体验的智能化之外,观车体验的智能化也不容忽视. 这是因为,随着数字化.智能化.个性化的趋势,消费者对汽车的需求和期待也越来越高, ...