當前位置:
首頁 > 知識 > DotNetCore跨平台~服務匯流排 事件匯流排的重新設計

DotNetCore跨平台~服務匯流排 事件匯流排的重新設計

理論閑話

之前在.netFramework平台用的好好的,可升級到.net core平台之後,由於不再需要二進位序列化,導致咱們的事件機制遇到了問題,之前大叔的事件一直是將處理程序序列化後進行存儲的,處理存儲的參數為事件源,一個事件源可以由多個處理程序訂閱,當事件源被發布時,這些被序列化的代碼段會被回調執行,這是大叔之前的思路,在RedisBus和MemoryBus里已經得到了實現,讀過大叔源代碼的同學應該有所了解了。

事件源和處理程序

   ///

/// 事件源
///

public class CreateUserCommand : BusData
{
public string UserName { get; set; }
}

   ///

/// 事件處理程序
///

public class CreateUserCommandHandler : IBusHandler
{
public void Handle(CreateUserCommand evt)
{
LoggerFactory.CreateLog.Logger_Debug(evt.UserName);
Console.WriteLine("CreateUserCommandHandler");
}
}

關於服務匯流排的實現方式

  1. RedisBus基於redis進行存儲,事件發布後,所有相關處理程序被回調,要求事件和處理程序是可序列化的
  2. MemoryBus基於應用伺服器緩存進行存儲,所有相關處理程序被回調,集群環境不是很適合
  3. IoCBus基於redis作為事件字典,處理程序由IoC容器進行注入,使用場合更廣

IoCBus實現思想與組成

  1. 應該有一個存儲事件與處理程序對應關係的字典
  2. 字典應該被持久化到中間件里
  3. 應該有個容器,去管理字典值與處理程序的關係

代碼實現

數據變更的定義

    ///

/// redis key
///

const string ESBKEY = "IoCESBBus";
///

/// redis事件字典
///

IDatabase redis = RedisManager.Instance.GetDatabase;
///

/// 模式鎖
///

private static object _objLock = new object;
///

/// 對於事件數據的存儲,目前採用內存字典
///

private readonly IContainer container = new AutofacContainer;

事件的統一訂閱

   public void SubscribeAll
{
var types = AssemblyHelper.GetTypesByInterfaces(typeof(IBusHandler<>));
Dictionary> keyDic = new Dictionary>;
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;
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 @event)
where TEvent : class, IBusData
{
var keyArr = JsonConvert.DeserializeObject>(redis.HashGet(ESBKEY, typeof(TEvent).Name));
foreach (var key in keyArr)
{
var item = container.ResolveNamed>(key);
item.Handle(@event);
}

}

說到這裡,大叔的服務匯流排的IoC實現方式就算是完成了,經過測試後,在.net core上表現也很不錯!

自己也驕傲一次,呵呵!

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 科技優家 的精彩文章:

ELK日誌框架(2):log4net.ElasticSearch+ Kibana實現日誌記錄和顯示
React Native之APK文件簽名及打包
mysql常見的優化方法
HTML5 伺服器推送事件

TAG:科技優家 |

您可能感興趣

ASP.NET Core Web API下事件驅動型架構的實現(三):基於RabbitMQ的事件匯流排
Patriot One開發的PatScan雷達系統旨在防止大規模槍擊事件
GDPR時代來臨後,英國Dixons Carphone公布嚴重數據泄露事件
潮流圈商標事件:Revenge Storm
如何用 Google Tag Manager標籤管理器設置GA onclick按鈕點擊事件
UPDATE:Kanye West就此前NIKE及Givenchy設計師抄襲事件作出回應!
事件 The Event
每日全球併購市場大事件!荷蘭汽車系統提供商Samvardhana Motherson,2.01億美元收購荷蘭汽車集團Reydel
領域事件及事件匯流排EventBus使用實踐
jQuery Mobile 事件
Mobileye/Drive.ai/特斯拉/Waymo/通用 自動駕駛最新大事件
Coinmarketcap將Bitcoin.com從BTC頁面移除據,Coincheck針對新經幣被盜事件致歉
Tiffany發布SOLO曲「Remember Me」 稱對泄露事件很傷心
繼早前舊型號iPhone電池限速事件後,Apple Watch Series 2出現電池發脹問題
每日全球併購市場大事件!美國媒體公司Hearst Communications,以28億美元收購美國金融信息服務提供商Fitch
經歷創傷事件後的20種常見軀體癥狀▎Physical Symptoms of Trauma
C 事件(Event)
FB及Cambridge Analytica因用戶數據泄露事件面臨訴訟
Science評論「抵制Nature子刊」事件:為什麼AI研究者熱愛arXiv與OpenReview?
每日全球併購市場大事件!加拿大包裝公司 Transcontinental,以13.2億美元收購美國包裝品生產商Coveris