• MediatR 10.0 发布 新增支持Stream等特性
  • 发布于 2个月前
  • 825 热度
    0 评论
  • 张蜚
  • 22 粉丝 35 篇博客
  •   
MediatR是.NET中的开源简单中介者模式实现.它通过一种进程内消息传递机制(无其他外部依赖),进行请求/响应、命令、查询、通知和事件的消息传递,并通过泛型来支持消息的智能调度。开源库地址是https://github.com/jbogard/MediatR

MediatR 10.0
2022年1月7日,MediatR 的作者发布了 10.0 。该版本主要有如下几个更新:

1.支持 Stream
即通过新的IStreamRequest来获得IAsyncEnumerable的响应结果; 可以通过类似下面的代码形式,定义 「StreamRequest」 和对应的 Handler
public class Sing : IStreamRequest<Song>
{
    public string Message { get; set; }
}

public class Song
{
    public string Message { get; set; }
}

public class SingHandler : IStreamRequestHandler<Sing, Song>
{
    private readonly TextWriter _writer;

    public SingHandler(TextWriter writer)
    {
        _writer = writer;
    }

    public async IAsyncEnumerable<Song> Handle(Sing request, [EnumeratorCancellation]CancellationToken cancellationToken)
    {
        await _writer.WriteLineAsync($"--- Handled Sing: {request.Message}, Song");
        yield return await Task.Run(() => new Song { Message = request.Message + "ing do" });
        yield return await Task.Run(() => new Song { Message = request.Message + "ing re" });
        yield return await Task.Run(() => new Song { Message = request.Message + "ing mi" });
        yield return await Task.Run(() => new Song { Message = request.Message + "ing fa" });
        yield return await Task.Run(() => new Song { Message = request.Message + "ing so" });
        yield return await Task.Run(() => new Song { Message = request.Message + "ing la" });
        yield return await Task.Run(() => new Song { Message = request.Message + "ing ti" });
        yield return await Task.Run(() => new Song { Message = request.Message + "ing do" });
    }
}
然后我们就用通过异步 foreach 来进行调用了:
await foreach (Song s in mediator.CreateStream(new Sing { Message = "Sing" }))
{
  // 根据流式响应的结果进行业务处理
}
也就是说这种StreamRequest我们需要通过IMediator的CreateStream方法来调用处理程序。

可以想到在一些需要异步跟踪长任务进度或者聊天交出程序等场景下蛮有用的。

2.新增一个独立的包 MediatR.Contracts
这样你就可以将 Request/Notification/StreamRequest 通过仅引用该包在一个独立的项目中定义,而将相关的Handler在另外一个项目中实现。例如下列场景:

1.API contracts
2.GRPC contracts

3.Blazor


3.Break Changes
当我们从 9.x 版本 升级到10.0 时,需要注意一下管线相关的定义要稍微修改一下,因为 IPipelineBehavior 接口中的泛型约束做了一点点修改。

IPipelineBehavior 的泛型约束 从 where TRequest notnull 修改为 where TRequest : IRequest<TResponse>
IRequestExceptionHandler 的泛型约束 从 where TRequest notnull 修改为 where TRequest : IRequest<TResponse>
IRequestPostProcessor 的泛型约束 从 where TRequest notnull 修改为 where TRequest : IRequest<TResponse>
IRequestPostProcessor 的泛型约束 从 where TRequest notnull 修改为 where TRequest : IRequest<TResponse>
所以,我们在使用 MediatR 的代码中如果有自定义的管线代码,需要在原来的基础上增加一点泛型约束即可,否则编译无法通过:
public class GenericPipelineBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
    where TRequest : IRequest<TResponse>
{
``


用户评论