Introduction to MediaTr
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 包管理器中搜索并安装:
MediatRMediatR.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;
}
}
如何触发?
你可以在 CreateUserRequestHandler 的 Handle 方法末尾注入 IMediator 并调用 Publish:
// 在 CreateUserRequestHandler 内部
await _mediator.Publish(new UserCreatedNotification { User = user });
📌 总结
通过引入 MediatR,我们成功地将业务逻辑从控制器中剥离出来,实现了清晰的关注点分离。
- 控制器只负责处理 HTTP 请求和响应。
- 处理器只负责具体的业务逻辑。
- MediatR 负责它们之间的通信。
这种架构模式不仅让代码更加整洁,也为未来的功能扩展和单元测试打下了坚实的基础。希望这篇指南能帮助你更好地组织 .NET 项目架构!

浙公网安备 33010602011771号