DotNetCore跨平台~服务总线_事件总线的重新设计
理论闲话
之前在.netFramework平台用的好好的,可升级到.net core平台之后,由于不再需要二进制序列化,导致咱们的事件机制遇到了问题,之前大叔的事件一直是将处理程序序列化后进行存储的,处理存储的参数为事件源,一个事件源可以由多个处理程序订阅,当事件源被发布时,这些被序列化的代码段会被回调执行,这是大叔之前的思路,在RedisBus和MemoryBus里已经得到了实现,读过大叔源代码的同学应该有所了解了。
事件源和处理程序
/// <summary>
/// 事件源
/// </summary>
public class CreateUserCommand : BusData
{
public string UserName { get; set; }
} /// <summary>
/// 事件处理程序
/// </summary>
public class CreateUserCommandHandler : IBusHandler<CreateUserCommand>
{
public void Handle(CreateUserCommand evt)
{
LoggerFactory.CreateLog().Logger_Debug(evt.UserName);
Console.WriteLine("CreateUserCommandHandler");
}
}
关于服务总线的实现方式
- RedisBus基于redis进行存储,事件发布后,所有相关处理程序被回调,要求事件和处理程序是可序列化的
- MemoryBus基于应用服务器缓存进行存储,所有相关处理程序被回调,集群环境不是很适合
- IoCBus基于redis作为事件字典,处理程序由IoC容器进行注入,使用场合更广
IoCBus实现思想与组成
- 应该有一个存储事件与处理程序对应关系的字典
- 字典应该被持久化到中间件里
- 应该有个容器,去管理字典值与处理程序的关系
代码实现
数据变更的定义
/// <summary>
/// redis key
/// </summary>
const string ESBKEY = "IoCESBBus";
/// <summary>
/// redis事件字典
/// </summary>
IDatabase redis = RedisManager.Instance.GetDatabase();
/// <summary>
/// 模式锁
/// </summary>
private static object _objLock = new object();
/// <summary>
/// 对于事件数据的存储,目前采用内存字典
/// </summary>
private readonly IContainer container = new AutofacContainer();
事件的统一订阅
public void SubscribeAll()
{
var types = AssemblyHelper.GetTypesByInterfaces(typeof(IBusHandler<>));
Dictionary<string, List<string>> keyDic = new Dictionary<string, List<string>>();
foreach (var item in types)
{
if (!item.IsGenericParameter)
{ TypeInfo typeInfo = IntrospectionExtensions.GetTypeInfo(item); foreach (var t in typeInfo.GetMethods().Where(i => i.Name == "Handle"))
{
//ioc name key
var eventKey = t.GetParameters().First().ParameterType.Name;
var key = t.GetParameters().First().ParameterType.Name + "_" + item.Name;
//eventhandler
var inter = typeof(IBusHandler<>).MakeGenericType(t.GetParameters().First().ParameterType);
container.Register(inter, item, key); if (keyDic.ContainsKey(eventKey))
{
var oldEvent = keyDic[eventKey];
oldEvent.Add(key);
}
else
{
var newEvent = new List<string>();
newEvent.Add(key);
keyDic.Add(eventKey, newEvent);
}
}
}
//redis存储事件与处理程序的映射关系
foreach (var hash in keyDic)
redis.HashSet(
ESBKEY,
hash.Key.ToString(),
JsonConvert.SerializeObject(hash.Value)); } }
事件的发布,相关处理程序会从容器中取出,并执行它们的Handler方法
public void Publish<TEvent>(TEvent @event)
where TEvent : class, IBusData
{
var keyArr = JsonConvert.DeserializeObject<List<string>>(redis.HashGet(ESBKEY, typeof(TEvent).Name));
foreach (var key in keyArr)
{
var item = container.ResolveNamed<IBusHandler<TEvent>>(key);
item.Handle(@event);
} }
说到这里,大叔的服务总线的IoC实现方式就算是完成了,经过测试后,在.net core上表现也很不错!
自己也骄傲一次,呵呵!
DotNetCore跨平台~服务总线_事件总线的重新设计的更多相关文章
- 【bird-java】分布式服务间的事件总线EventBus
什么是EventBusEventBus是对发布-订阅模式的一种实现.其以一种非常优雅的方式实现了组件间的解耦与通信,在Android开发.DDD等领域都有非常广泛的应用. 事件流大致如下: Produ ...
- DotNetCore跨平台~文章索引~永久更新
本索引目录主要包括仓储大叔对dotnet core架构的研究与知识积累,从2016年开始进行撰写,到今天已经有一年多了,其中有一些小知识,小技巧,小应用,希望给大家在开发时一些启发,也希望dotnet ...
- ASP.NET Core Web API下事件驱动型架构的实现(三):基于RabbitMQ的事件总线
在上文中,我们讨论了事件处理器中对象生命周期的问题,在进入新的讨论之前,首先让我们总结一下,我们已经实现了哪些内容.下面的类图描述了我们已经实现的组件及其之间的关系,貌似系统已经变得越来越复杂了. 其 ...
- Autofac解耦事件总线
事件总线之Autofac解耦 事件总线是通过一个中间服务,剥离了常规事件的发布与订阅(消费)强依赖关系的一种技术实现.事件总线的基础知识可参考圣杰的博客[事件总线知多少] 本片博客不再详细概述事件总线 ...
- RabbitMQ的事件总线
RabbitMQ的事件总线 在上文中,我们讨论了事件处理器中对象生命周期的问题,在进入新的讨论之前,首先让我们总结一下,我们已经实现了哪些内容.下面的类图描述了我们已经实现的组件及其之间的关系,貌似系 ...
- 重温.NET下Assembly的加载过程 ASP.NET Core Web API下事件驱动型架构的实现(三):基于RabbitMQ的事件总线
重温.NET下Assembly的加载过程 最近在工作中牵涉到了.NET下的一个古老的问题:Assembly的加载过程.虽然网上有很多文章介绍这部分内容,很多文章也是很久以前就已经出现了,但阅读之后 ...
- 浅入 ABP 系列(4):事件总线
浅入 ABP 系列(4):事件总线 版权护体作者:痴者工良,微信公众号转载文章需要 <NCC开源社区>同意. 目录 浅入 ABP 系列(4):事件总线 事件总线 关于事件总线 为什么需要这 ...
- Android事件总线
Android中Activity.Service.Fragment之间的相互通信比较麻烦,主要有以下一些方法: (1)使用广播,发送者发出广播,接收者接收广播后进行处理: (2)使用Handler和M ...
- 事件总线(Event Bus)知多少
源码路径:Github-EventBus 简书同步链接 1. 引言 事件总线这个概念对你来说可能很陌生,但提到观察者(发布-订阅)模式,你也许就很熟悉.事件总线是对发布-订阅模式的一种实现.它是一种集 ...
随机推荐
- Customer segmentation – LifeCycle Grids, CLV and CAC with R(转)
We studied a very powerful approach for customer segmentation in the previous post, which is based o ...
- 【webpack】webpack-dev-server生猛上手——让我们来搭一个webpack的微服务器吧!
[前言]:因为最近在搞百度地图API的时候到了webpack的externals,才发现我之前都只是用webpack做一些搭建完项目后的"收尾工作"--即打包,而没有把它纳入到 ...
- c++ 库函数返回的字符串指针是否需要手动释放
#include <stdio.h> char * tmpnam(char *s); tmpnam函数返回一个不与任何已存在文件同名的有效文件名,如果字符串s不为空,文件名也会写入它.对t ...
- intel hex 格式的几个链接
intel hex GENERAL: INTEL HEX FILE FORMAT Intel Hex文件格式说明 - starspace - 博客园 C# Hex文件转bin文件 - bule - 博 ...
- 谈谈this对象
通过平常的使用简单总结了一下不同形式的函数调用下this的指向,函数的调用形式决定了this的指向.就简单分析一下以下几种情况: 情况一:纯粹的函数调用 eg: var x=1; function f ...
- 给Linux系统/网络管理员准备的Nmap命令的29个实用范例
我将用两个不同的部分来涵盖大部分NMAP的使用方法,这是nmap关键的第一部分.在下面的设置中,我使用两台已关闭防火墙的服务器来测试Nmap命令的工作情况. 192.168.0.100 – serve ...
- 文件快速删除工具, 解决你的node_modules
摘要: 还在为删除文件慢烦恼吗?强大工具dlf来帮助你.作为一名前端开发,最常见的就是node_modules,如果dependencies很多,osx系统删除还好,Windows用户就麻烦了.本文分 ...
- angular.js的ng-app 指令定义一个 AngularJS 应用程序。
<!DOCTYPE html> <html lang="en" ng-app> <head> <meta charset="UT ...
- AS3批量替换文件
在做项目时,经过会遇到资源替换问题.比如配音公司,提供了一批八九百个配音MP3文件,用到后面却发现有些配音不能正常使用.可能是十几个,也可能是一两百个.只能是配音公司重新提供.因为之前的配音资源,已经 ...
- [转] 面向对象原则之GOF是招式,九大原则才是精髓
只有到了一定层次后才会真正的深入体会到面向对象的一些知识点啊! 不谈具体程序,谈的是你对软件的理解 模式: 每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心. “模式”这个 ...