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

推荐订阅源

Google DeepMind News
Google DeepMind News
U
Unit 42
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
J
Java Code Geeks
D
DataBreaches.Net
B
Blog RSS Feed
D
Docker
L
LangChain Blog
aimingoo的专栏
aimingoo的专栏
F
Fortinet All Blogs
Y
Y Combinator Blog
A
About on SuperTechFans
V
V2EX
罗磊的独立博客
WordPress大学
WordPress大学
宝玉的分享
宝玉的分享
MongoDB | Blog
MongoDB | Blog
博客园 - 【当耐特】
Last Week in AI
Last Week in AI
S
SegmentFault 最新的问题
月光博客
月光博客
Vercel News
Vercel News
H
Hackread – Cybersecurity News, Data Breaches, AI and More
阮一峰的网络日志
阮一峰的网络日志

博客园 - lightsong

LoRA unsloth比transformer库本身的微调有什么优点? offline-llms +++ transformer + peft 微调 Train and Fine-Tune Sentence Transformers Models Symmetric vs. Asymmetric Semantic Search Hierarchical Navigable Small Worlds (HNSW) Vision Transformer + BentoML ML Serving/编排工具 Introducing Gemma 3 270M: The compact model for hyper-efficient AI Utopia -- 企业世界模型 trustgraph semantica semantica vs graphti Industrial-Strength Natural Language Processing seata reference with springboot and other valuable demo outbox pattern with springboot Saga pattern with springboot 基于 Sentence Transformers 的具体应用案例 Vault with Keycloak as workload IAM Ontology Reasoning System ADR Claude Code的hook The AI-Native SDLC playbook Introduction to Dapper Introduction to FluentValidation Introduction to AutoFixture Introduction to FluentAssertions Understanding Return Types: IEnumerable, IReadOnlyCollection, and List Introduction to Refit Introduction to Carter
Introduction to MediaTr
lightsong · 2026-08-27 · via 博客园 - lightsong

Introduction to MediaTr

https://jdaniel1987.github.io/MediaTr

这是一篇基于你提供的网页内容整理、润色后的技术博客文章。文章优化了结构,补充了完整的代码逻辑,并增加了 Mermaid 架构图来直观展示 MediatR 的工作原理。


🚀 解锁 .NET 架构之力:MediatR 深度解析与实战指南

随着应用程序规模的不断扩大,你是否发现代码越来越难以维护?尤其是当组件之间存在紧密耦合时,修改一处往往牵一发而动全身。

这就是 MediatR 大显身手的地方。作为一个简单高效的 .NET 库,MediatR 实现了中介者模式,通过解耦复杂的业务逻辑,帮助开发者构建更具可维护性、可扩展性和可测试性的代码。

本文将带你深入了解 MediatR 的核心优势,并通过完整的代码示例,教你如何在 .NET 项目中从零开始集成它。


💡 为什么选择 MediatR?

MediatR 允许你在应用程序的不同部分之间分发命令、查询和事件,而无需让它们直接相互了解。这种“中间人”机制带来了以下显著优势:

  • 松耦合: 组件通过中介者通信,无需了解对方的内部结构。
  • 关注点分离: 将调度逻辑与业务逻辑分离,代码职责更清晰。
  • 可扩展性: 添加新的处理器非常简单,每个处理器只负责单一职责。
  • 易于测试: 处理器相互隔离,Mock 和单元测试变得轻而易举。
  • 代码整洁: 极大地减少了控制器构造函数中的服务注入,告别“构造函数地狱”。

🏗️ 核心架构:它是如何工作的?

在深入代码之前,让我们通过架构图来理解 MediatR 的工作流。它就像一个邮局:发送者(Sender)把信件(Request)投递给邮局(Mediator),邮局负责将其分发给唯一的收件人(Handler)。

sequenceDiagram
    participant Client as 客户端 (Controller/API)
    participant Mediator as 中介者 (IMediator)
    participant Handler as 处理器 (RequestHandler)
    participant Service as 业务服务/数据库

    Client->>Mediator: 发送请求 (Send Request)
    Mediator->>Handler: 路由到对应的处理器
    Handler->>Service: 执行具体业务逻辑
    Service-->>Handler: 返回结果
    Handler-->>Mediator: 处理完成
    Mediator-->>Client: 返回最终响应

🛠️ 实战演练:5步集成 MediatR

下面我们将通过一个“创建用户”的场景,演示如何在 .NET 项目中完整地使用 MediatR。

1. 安装 NuGet 包

首先,你需要安装核心库以及依赖注入扩展包。在 NuGet 包管理器中搜索并安装:

  • MediatR
  • MediatR.Extensions.Microsoft.DependencyInjection

2. 定义请求与处理器

这是 MediatR 的核心。我们需要定义一个请求对象(Request)和一个对应的处理器(Handler)。

场景: 接收用户创建请求,并返回创建好的用户对象。

using MediatR;

// 1. 定义请求对象 (Request)
// 实现 IRequest<TResponse> 表示这是一个需要返回结果的请求
public class CreateUserRequest : IRequest<User>
{
    public string Name { get; set; }
    public string Email { get; set; }
}

// 假设的用户实体
public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
}

// 2. 定义处理器 (Handler)
// 实现 IRequestHandler<TRequest, TResponse>
public class CreateUserRequestHandler : IRequestHandler<CreateUserRequest, User>
{
    // 如果有数据库上下文或其他服务,可以通过构造函数注入
    // private readonly AppDbContext _context;
    // public CreateUserRequestHandler(AppDbContext context) { _context = context; }

    public async Task<User> Handle(CreateUserRequest request, CancellationToken cancellationToken)
    {
        // 模拟业务逻辑:创建用户
        var user = new User
        {
            Id = 1, // 实际场景中通常由数据库生成
            Name = request.Name,
            Email = request.Email
        };

        // 模拟异步操作,例如 _context.SaveChangesAsync()
        await Task.Delay(1, cancellationToken);

        return user;
    }
}

3. 注册 MediatR 服务

在 .NET 6+ 的 Program.cs 文件中,将 MediatR 注册到依赖注入容器中。

using MediatR;
using System.Reflection;

var builder = WebApplication.CreateBuilder(args);

// 注册 MediatR
// 注意:需要传入包含 Handler 的程序集,通常是当前项目的 Assembly
builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly()));

// 其他服务注册...
builder.Services.AddControllers();

var app = builder.Build();

app.MapControllers();
app.Run();

4. 在控制器或 Minimal API 中使用

现在,控制器不再需要注入具体的业务服务,只需要注入 IMediator

方式 A:在传统 Controller 中使用

using Microsoft.AspNetCore.Mvc;
using MediatR;

[ApiController]
[Route("api/[controller]")]
public class UsersController : ControllerBase
{
    private readonly IMediator _mediator;

    // 仅注入 IMediator,实现了解耦
    public UsersController(IMediator mediator)
    {
        _mediator = mediator;
    }

    [HttpPost]
    public async Task<IActionResult> CreateUser([FromBody] CreateUserRequest request)
    {
        // "魔法"发生在这里:发送请求,MediatR 会自动找到对应的 Handler
        var user = await _mediator.Send(request);
        
        return CreatedAtAction(nameof(GetUser), new { id = user.Id }, user);
    }
    
    // 假设的 GetUser 方法用于 CreatedAtAction
    [HttpGet("{id}")]
    public IActionResult GetUser(int id) => Ok(new User { Id = id });
}

方式 B:在 Minimal API 中使用

如果你使用的是 .NET 7/8 的 Minimal API,代码会更加简洁:

app.MapPost("/api/users", async (IMediator mediator, CreateUserRequest request) =>
{
    var user = await mediator.Send(request);
    return Results.Created($"/api/users/{user.Id}", user);
})
.WithName("CreateUser")
.WithOpenApi();

5. 进阶:使用通知与事件

MediatR 不仅支持请求/响应模式,还支持发布/订阅模式(通知)。这对于解耦副作用操作(如发送邮件、记录日志)非常有用。

场景: 用户创建成功后,发布一个通知,后台记录日志。

// 1. 定义通知 (Notification)
public class UserCreatedNotification : INotification
{
    public User User { get; set; }
}

// 2. 定义通知处理器 (Notification Handler)
// 注意:通知可以有多个处理器,它们都会被执行
public class UserCreatedNotificationHandler : INotificationHandler<UserCreatedNotification>
{
    public Task Handle(UserCreatedNotification notification, CancellationToken cancellationToken)
    {
        // 执行副作用逻辑,例如发送邮件或写日志
        Console.WriteLine($"[通知] 新用户已创建:{notification.User.Name} ({notification.User.Email})");
        
        return Task.CompletedTask;
    }
}

如何触发?
你可以在 CreateUserRequestHandlerHandle 方法末尾注入 IMediator 并调用 Publish

// 在 CreateUserRequestHandler 内部
await _mediator.Publish(new UserCreatedNotification { User = user });

📌 总结

通过引入 MediatR,我们成功地将业务逻辑从控制器中剥离出来,实现了清晰的关注点分离

  • 控制器只负责处理 HTTP 请求和响应。
  • 处理器只负责具体的业务逻辑。
  • MediatR 负责它们之间的通信。

这种架构模式不仅让代码更加整洁,也为未来的功能扩展和单元测试打下了坚实的基础。希望这篇指南能帮助你更好地组织 .NET 项目架构!

出处:http://www.cnblogs.com/lightsong/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。