惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

J
Java Code Geeks
G
Google Developers Blog
Blog — PlanetScale
Blog — PlanetScale
U
Unit 42
A
About on SuperTechFans
Vercel News
Vercel News
B
Blog
Martin Fowler
Martin Fowler
MyScale Blog
MyScale Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
腾讯CDC
D
Docker
V
Visual Studio Blog
博客园 - 叶小钗
The Cloudflare Blog
Jina AI
Jina AI
B
Blog RSS Feed
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
WordPress大学
WordPress大学
T
Tailwind CSS Blog
MongoDB | Blog
MongoDB | Blog
D
DataBreaches.Net
月光博客
月光博客
大猫的无限游戏
大猫的无限游戏

博客园 - dudu

test .NET CQRS 的实现中引入 ReadOnlyRepository 什么是 Agentic ? 初试 Microsoft Agent Framework 初识 Microsoft Agent Framework:一句话介绍 ASP.NET Core 中读取 UserAgent 的正确姿势 记录一下对 ASP.NET Core Middleware 进行单元测试的代码 C# 实现通用的 IdEqualityComparer 用 Angular Signal Inputs 完成一个组件的重构 量子网络操作系统 QNodeOS 资料收集 Kubernetes 集群上部署 Open WebUI 在 Kubernetes 集群的 GPU 节点上部署 Ollama 尝试在 Kubernetes 集群上用阿里云 GPU 实例部署 Ollama + DeekSeek-R1 阿里云 GPU 实例云服务器本地部署 DeepSeek R1 尝试使用阿里云计算巢部署 DeepSeek-R1 Angular 中依赖注入问题造成 Observable 订阅不更新 园子博客后台 Angular 升级:手工迁移至 Standalone Component Angular 中使用 ChildContent 记录 园子博客后台升级至 angular 19 后 eslint 9 迁移记录 学习大模型(LLM)的英文好文收集
初试 .NET CQRS 开源库 LiteBus
dudu · 2026-02-22 · via 博客园 - dudu

最近在找 MediatR 的替代,看了 LiteBus 作者的博文 LiteBus: A Free and Ambitious Alternative to MediatR for .NET Applications 后,看中了 LiteBus,这篇博文记录一下初步使用 LiteBus 的步骤。

Query 层安装 nuget 包 LiteBus.Queries.Abstractions

dotnet add package LiteBus.Queries.Abstractions

实现 IQuery 接口,DTO 使用泛型

public record GetBlogPublishedPostsQuery<TDto>(int BlogId) : IQuery<TDto>;

Web 层安装 nuget 包 LiteBus.Queries.Extensions.Microsoft.DependencyInjection

dotnet add package LiteBus.Queries.Extensions.Microsoft.DependencyInjection

将 LiteBus 注册到依赖注入容器

services.AddLiteBus(liteBus =>
{
    var appAssembly = typeof(GetBlogPublishedPostsQuery<BlogPostDto>).Assembly;
    liteBus.AddQueryModule(module => module.RegisterFromAssembly(appAssembly));
});

在 Minimal API 中使用 IQueryMediator 发起查询并获取结果

app.MapGet(
    ""/blogs/{blogId:int}"",
    async ([Required] int blogId, IQueryMediator mediator) =>
    {
        var posts = await mediator.QueryAsync(new GetBlogPublishedPostsQuery<BlogPostDto>(blogId));
        return Results.Ok(posts);
    });

Query 层 Query Handler 的实现代码

public class GetBlogPublishedPostsQueryHandler<TDto>(BlogDbContext dbContext)
    : IQueryHandler<GetBlogPublishedPostsQuery<TDto>, IEnumerable<TDto>>
{
    public async Task<IEnumerable<TDto>> HandleAsync(
        GetBlogPublishedPostsQuery<TDto> query,
        CancellationToken cancellationToken)
    {
        var posts = await dbContext.Set<BlogPost>()
            .AsNoTracking()
            .PublishedByBlogId(query.BlogId)
            .OrderByDescending(p => p.DateAdded)
            .ProjectToType<TDto>()
            .ToListAsync(cancellationToken);
        return posts;
    }
}