.NET 事件匯流排,簡化項目、類庫、執行緒、服務等之間的通訊,程式碼更少,品質更好。
- 2021 年 10 月 25 日
- 筆記
Jaina
.NET 事件匯流排,簡化項目、類庫、執行緒、服務等之間的通訊,程式碼更少,品質更好。
安裝
Install-Package Jaina
dotnet add package Jaina
快速入門
我們在主頁上有不少例子,這是讓您入門的第一個:
- 定義事件訂閱者
ToDoEventSubscriber
:
// 實現 IEventSubscriber 介面
public class ToDoEventSubscriber : IEventSubscriber
{
private readonly ILogger<ToDoEventSubscriber> _logger;
public ToDoEventSubscriber(ILogger<ToDoEventSubscriber> logger)
{
_logger = logger;
}
// 標記 [EventSubscribe(事件 Id)] 特性
[EventSubscribe("ToDo:Create")]
public async Task CreateToDo(EventHandlerExecutingContext context)
{
var todo = context.Source;
_logger.LogInformation("創建一個 ToDo:{Name}", todo.Payload);
await Task.CompletedTask;
}
}
- 創建控制器
ToDoController
,依賴注入IEventPublisher
服務:
[Route("api/[controller]/[action]")]
[ApiController]
public class ToDoController : ControllerBase
{
// 依賴注入事件發布者 IEventPublisher
private readonly IEventPublisher _eventPublisher;
public ToDoController(IEventPublisher eventPublisher)
{
_eventPublisher = eventPublisher;
}
// 發布 ToDo:Create 消息
[HttpPost]
public async Task CreateDoTo(string name)
{
await _eventPublisher.PublishAsync(new ChannelEventSource("ToDo:Create", name));
}
}
- 在
Startup.cs
註冊EventBus
服務:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// 註冊 EventBus 服務
services.AddEventBus(buidler =>
{
// 註冊 ToDo 事件訂閱者
buidler.AddSubscriber<ToDoEventSubscriber>();
});
// ....
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// ....
}
}
- 運行項目:
info: Jaina.Samples.ToDoEventSubscriber[0]
創建一個 ToDo:Jaina
高級教程
1. 自定義事件源 IEventSource
Jaina 使用 IEventSource
作為消息載體,任何實現該介面的類都可以充當消息載體。
如需自定義,只需實現 IEventSource
介面即可:
public class ToDoEventSource : IEventSource
{
// 自定義屬性
public string ToDoName { get; }
/// <summary>
/// 事件 Id
/// </summary>
public string EventId { get; }
/// <summary>
/// 事件承載(攜帶)數據
/// </summary>
public object Payload { get; }
/// <summary>
/// 取消任務 Token
/// </summary>
/// <remarks>用於取消本次消息處理</remarks>
public CancellationToken CancellationToken { get; }
/// <summary>
/// 事件創建時間
/// </summary>
public DateTime CreatedTime { get; } = DateTime.UtcNow;
}
使用:
await _eventPublisher.PublishAsync(new ToDoEventSource {
EventId = "ToDo:Create",
ToDoName = "我的 ToDo Name"
});
2. 自定義事件源存儲器 IEventSourceStorer
Jaina 默認採用 Channel
作為事件源 IEventSource
存儲器,開發者可以使用任何消息隊列組件進行替換,如 Kafka、RabbitMQ、ActiveMQ
等,也可以使用部分資料庫 Redis、SQL Server、MySql
實現。
如需自定義,只需實現 IEventSourceStorer
介面即可:
public class RedisEventSourceStorer : IEventSourceStorer
{
private readonly IRedisClient _redisClient;
public RedisEventSourceStorer(IRedisClient redisClient)
{
_redisClient = redisClient;
}
// 往 Redis 中寫入一條
public async ValueTask WriteAsync(IEventSource eventSource, CancellationToken cancellationToken)
{
await _redisClient.WriteAsync(...., cancellationToken);
}
// 從 Redis 中讀取一條
public async ValueTask<IEventSource> ReadAsync(CancellationToken cancellationToken)
{
return await _redisClient.ReadAsync(...., cancellationToken);
}
}
最後,在註冊 EventBus
服務中替換默認 IEventSourceStorer
:
services.AddEventBus(buidler =>
{
// 替換事件源存儲器
buidler.ReplaceStorer<RedisEventSourceStorer>();
});
3. 自定義事件發布者 IEventPublisher
Jaina 默認內置基於 Channel
的事件發布者 ChannelEventPublisher
。
如需自定義,只需實現 IEventPublisher
介面即可:
public class ToDoEventPublisher : IEventPublisher
{
private readonly IEventSourceStorer _eventSourceStorer;
public ChannelEventPublisher(IEventSourceStorer eventSourceStorer)
{
_eventSourceStorer = eventSourceStorer;
}
public async Task PublishAsync(IEventSource eventSource)
{
await _eventSourceStorer.WriteAsync(eventSource, eventSource.CancellationToken);
}
}
最後,在註冊 EventBus
服務中替換默認 IEventPublisher
:
services.AddEventBus(buidler =>
{
// 替換事件源存儲器
buidler.ReplacePublisher<ToDoEventPublisher>();
});
4. 添加事件執行監視器 IEventHandlerMonitor
Jaina 提供了 IEventHandlerMonitor
監視器介面,實現該介面可以監視所有訂閱事件,包括 執行之前、執行之後,執行異常,共享上下文數據
。
如添加 ToDoEventHandlerMonitor
:
public class ToDoEventHandlerMonitor : IEventHandlerMonitor
{
private readonly ILogger<ToDoEventHandlerMonitor> _logger;
public ToDoEventHandlerMonitor(ILogger<ToDoEventHandlerMonitor> logger)
{
_logger = logger;
}
public Task OnExecutingAsync(EventHandlerExecutingContext context)
{
_logger.LogInformation("執行之前:{EventId}", context.Source.EventId);
return Task.CompletedTask;
}
public Task OnExecutedAsync(EventHandlerExecutedContext context)
{
_logger.LogInformation("執行之後:{EventId}", context.Source.EventId);
if (context.Exception != null)
{
_logger.LogError(context.Exception, "執行出錯啦:{EventId}", context.Source.EventId);
}
return Task.CompletedTask;
}
}
最後,在註冊 EventBus
服務中註冊 ToDoEventHandlerMonitor
:
services.AddEventBus(buidler =>
{
// 主鍵事件執行監視器
buidler.AddMonitor<ToDoEventHandlerMonitor>();
});
5. 自定義事件處理程式執行器 IEventHandlerExecutor
Jaina 提供了 IEventHandlerExecutor
執行器介面,可以讓開發者自定義事件處理函數執行策略,如 超時控制,失敗重試、熔斷等等
。
如添加 RetryEventHandlerExecutor
:
public class RetryEventHandlerExecutor : IEventHandlerExecutor
{
public async Task ExecuteAsync(EventHandlerExecutingContext context, Func<EventHandlerExecutingContext, Task> handler)
{
// 如果執行失敗,每隔 1s 重試,最多三次
await Retry(async () => {
await handler(context);
}, 3, 1000);
}
}
最後,在註冊 EventBus
服務中註冊 RetryEventHandlerExecutor
:
services.AddEventBus(buidler =>
{
// 主鍵事件執行監視器
buidler.AddExecutor<RetryEventHandlerExecutor>();
});
文檔
您可以在主頁找到 Jaina 文檔。
貢獻
該存儲庫的主要目的是繼續發展 Jaina 核心,使其更快、更易於使用。Jaina 的開發在 Gitee 上公開進行,我們感謝社區貢獻錯誤修復和改進。
許可證
Jaina 採用 MulanPSL-2.0 開源許可證。
Copyright (c) 2020-2021 百小僧, Baiqian Co.,Ltd.
Jaina is licensed under Mulan PSL v2.
You can use this software according to the terms andconditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
//gitee.com/dotnetchina/Jaina/blob/master/LICENSE
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUTWARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.