日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > asp.net >内容正文

asp.net

ASP.NET Core 消息传递:MediatR

發(fā)布時(shí)間:2023/12/4 asp.net 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ASP.NET Core 消息传递:MediatR 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

MediatR[1] 是參考中介者模式實(shí)現(xiàn)的一個(gè) .NET 工具類庫(kù),支持在進(jìn)程內(nèi)以單播或多播的形式進(jìn)行消息傳遞,通過使用 MediatR 可實(shí)現(xiàn)消息的發(fā)送和處理充分解耦。

在介紹 MediatR 之前,先簡(jiǎn)單了解下中介者模式。中介者模式主要是指定義一個(gè)中介對(duì)象來調(diào)度一系列對(duì)象之間的交互關(guān)系,各對(duì)象之間不需要顯式的相互引用,降低耦合性。如下對(duì)比圖(普通模式與中介者模式的區(qū)別):

實(shí)際上從 MediatR 源代碼中可以看出,它本身也并非標(biāo)準(zhǔn)中介者模式的實(shí)現(xiàn),所以這里簡(jiǎn)單了解即可。接下來將先介紹 MediatR 的兩種消息傳遞方式的使用方式,然后再分析其具體實(shí)現(xiàn)。

創(chuàng)建一個(gè) .NET Core Web API 項(xiàng)目并安裝 MediatR.Extensions.Microsoft.DependencyInjection NuGet 包(已含 MediatR NuGet ?包),然后在 ConfigureServices 中注冊(cè)服務(wù)。

// 掃描 Startup 所在程序集內(nèi)實(shí)現(xiàn)了 Handler 的對(duì)象并添加到 IoC 容器中 services.AddMediatR(typeof(Startup));

可通過查看 MediatR.Extensions.Microsoft.DependencyInjection[2] ?說明了解 AddMediatR 具體包含了哪些服務(wù)的注冊(cè)以及各注冊(cè)對(duì)象的生命周期,基本通過以上一行代碼就已經(jīng)把 MediatR 相關(guān)的服務(wù)全部注冊(cè)到 IoC 容器中。

單播消息傳遞

單播消息傳遞主要涉及 IRequest(消息類型) 和 IRequestHandler(消息處理) 兩個(gè)接口。

定義接口 IRequest 的實(shí)現(xiàn)類,string 指定消息處理方法的返回值類型,如下:

public class GenericRequest : IRequest<string> {public string Name { get; set; } }

定義接口 IRequestHandler 的實(shí)現(xiàn)類,GenericRequest 指定此 Handler 要處理的消息類型,string 指定消息處理方法的返回值類型(與 IRequest 指定的泛型類型一致),另外需實(shí)現(xiàn) Handle 方法,如下:

public class GenericRequestHandler : IRequestHandler<GenericRequest, string> {public Task<string> Handle(GenericRequest request, CancellationToken cancellationToken){return Task.FromResult($"This is {request.Name}");} }

在 Controller 中進(jìn)行調(diào)用測(cè)試:

private readonly IMediator _mediator;public MediatorController(IMediator mediator) {_mediator = mediator; }[HttpGet] public async Task<string> GenericRequest() {var result = await _mediator.Send(new GenericRequest{Name = "GenericRequest"});return result; }

另外針對(duì)不同的代碼實(shí)現(xiàn)方式,有其他的 request-types[3] 可選,本質(zhì)上還是基于 IRequest 和 IRequestHandler 的擴(kuò)展。

多播消息傳遞

多播消息傳遞主要涉及 INotification(消息類型) 和 INotificationHandler(消息處理) 兩個(gè)接口,另外多播消息傳遞是無返回值的。

定義接口 INotification 的實(shí)現(xiàn)類,如下:

public class GenericNotification : INotification {public string Name { get; set; } }

定義接口 INotificationHandler 的實(shí)現(xiàn)類,GenericNotification 指定此 Handler 要處理的消息類型,另外需實(shí)現(xiàn) Handle 方法,這里將為此消息類型定義兩個(gè) NotificationHandler 實(shí)現(xiàn)類,如下:

public class GenericANotificationHandler : INotificationHandler<GenericNotification> {public Task Handle(GenericNotification notification, CancellationToken cancellationToken){Console.WriteLine($"A {notification.Name}");return Task.CompletedTask;} } public class GenericBNotificationHandler : INotificationHandler<GenericNotification> {public Task Handle(GenericNotification notification, CancellationToken cancellationToken){Console.WriteLine($"B {notification.Name}");return Task.CompletedTask;} }

在 Controller 中進(jìn)行調(diào)用測(cè)試:

[HttpGet] public async Task GenericNotification() {await _mediator.Publish(new GenericNotification{Name = "GenericNotification"}); }

原理分析

建議閱讀下源碼,代碼量少且結(jié)構(gòu)清晰,基本理解沒什么難度

通過前面的介紹可以了解在 MediatR 中面向開發(fā)者的核心接口主要是 IRequest&IRequestHandler 、INotification&INotificationHandler、IMediator 。

如下 IMediator ?的實(shí)現(xiàn)類 Mediator 中的定義:

public class Mediator : IMediator {private readonly ServiceFactory _serviceFactory;private static readonly ConcurrentDictionary<Type, object> _requestHandlers = new ConcurrentDictionary<Type, object>();private static readonly ConcurrentDictionary<Type, NotificationHandlerWrapper> _notificationHandlers = new ConcurrentDictionary<Type, NotificationHandlerWrapper>(); }

首先定義了 ServiceFactory 對(duì)象,它代表當(dāng)前應(yīng)用程序的 IoC 容器,在應(yīng)用初始化階段進(jìn)行了注入,如 MediatR.Extensions.Microsoft.DependencyInjection 已包含了對(duì)應(yīng)的 ServiceFactory 注冊(cè)[4]。由于 ServiceFactory 可自定義,所以開發(fā)中也完全可以選擇其他的含 IoC 容器功能的框架,如 Autofac、Castle Windsor、DryIoc 等。

另外定義 _requestHandlers 和 _notificationHandlers 分別保存單播和多播消息對(duì)象類型對(duì)應(yīng)的 HandlerWrapper 對(duì)象,HandlerWrapper 的主要是對(duì) ServiceFactory 對(duì)象的傳遞,最終通過 ServiceFactory 從 IoC 容器中獲取對(duì)應(yīng)消息類型的 Handler 對(duì)象。

MeidatR 還支持為單播消息定義消息處理的 Pipeline,如通過實(shí)現(xiàn) IRequestPreProcessor 、IRequestPostProcessor 在消息處理前后自定義處理行為,通過實(shí)現(xiàn) IRequestExceptionHandler、IRequestExceptionAction 在異常時(shí)自定義處理行為,這些實(shí)現(xiàn)類也是通過 ServiceFactory 從 IoC 容器中獲取。

以下是單播消息處理的核心代碼:

public override Task<TResponse> Handle(IRequest<TResponse> request, CancellationToken cancellationToken, ServiceFactory serviceFactory) {Task<TResponse> Handler() => GetHandler<IRequestHandler<TRequest, TResponse>>(serviceFactory).Handle((TRequest) request, cancellationToken);return serviceFactory.GetInstances<IPipelineBehavior<TRequest, TResponse>>().Reverse().Aggregate((RequestHandlerDelegate<TResponse>) Handler, (next, pipeline) => () => pipeline.Handle((TRequest)request, cancellationToken, next))(); }

首先從 ServiceFactory 獲取 IPipelineBehavior,然后通 Linq 的 Reverse 方法進(jìn)行順序顛倒,最后通過 Aggregate 進(jìn)行委托傳遞并執(zhí)行,所以最終執(zhí)行順序是 RequestPreProcessorBehavior → ?Handler → RequestPostProcessorBehavior,這里的實(shí)現(xiàn)可能較難理解,核心是 Aggregate 的使用。

總結(jié)

MediatR 在實(shí)現(xiàn)上核心是通過保存消息請(qǐng)求對(duì)象與消息處理對(duì)象的關(guān)系,配合 IoC 容器實(shí)現(xiàn)的消息傳遞解耦。在實(shí)際應(yīng)用中,通過 MediatR 多播消息傳遞可以使代碼實(shí)現(xiàn)邏輯上更加簡(jiǎn)潔,另外也有較多的文章介紹了通過 ?MediatR 實(shí)現(xiàn) CQRS、EventBus 等。

參考資料

[1]

MediatR: https://github.com/jbogard/MediatR

[2]

MediatR.Extensions.Microsoft.DependencyInjection: https://github.com/jbogard/MediatR.Extensions.Microsoft.DependencyInjection

[3]

request-types: https://github.com/jbogard/MediatR/wiki#request-types

[4]

ServiceFactory 注冊(cè): https://github.com/jbogard/MediatR.Extensions.Microsoft.DependencyInjection/blob/master/src/MediatR.Extensions.Microsoft.DependencyInjection/Registration/ServiceRegistrar.cs#L219

總結(jié)

以上是生活随笔為你收集整理的ASP.NET Core 消息传递:MediatR的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。