









https://jdaniel1987.github.io/MediaTr
这是一篇基于你提供的网页内容整理、润色后的技术博客文章。文章优化了结构,补充了完整的代码逻辑,并增加了 Mermaid 架构图来直观展示 MediatR 的工作原理。
随着应用程序规模的不断扩大,你是否发现代码越来越难以维护?尤其是当组件之间存在紧密耦合时,修改一处往往牵一发而动全身。
这就是 MediatR 大显身手的地方。作为一个简单高效的 .NET 库,MediatR 实现了中介者模式,通过解耦复杂的业务逻辑,帮助开发者构建更具可维护性、可扩展性和可测试性的代码。
本文将带你深入了解 MediatR 的核心优势,并通过完整的代码示例,教你如何在 .NET 项目中从零开始集成它。
MediatR 允许你在应用程序的不同部分之间分发命令、查询和事件,而无需让它们直接相互了解。这种“中间人”机制带来了以下显著优势:
在深入代码之前,让我们通过架构图来理解 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: 返回最终响应
下面我们将通过一个“创建用户”的场景,演示如何在 .NET 项目中完整地使用 MediatR。
首先,你需要安装核心库以及依赖注入扩展包。在 NuGet 包管理器中搜索并安装:
MediatRMediatR.Extensions.Microsoft.DependencyInjection这是 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;
}
}
在 .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();
现在,控制器不再需要注入具体的业务服务,只需要注入 IMediator。
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 });
}
如果你使用的是 .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();
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,我们成功地将业务逻辑从控制器中剥离出来,实现了清晰的关注点分离。
这种架构模式不仅让代码更加整洁,也为未来的功能扩展和单元测试打下了坚实的基础。希望这篇指南能帮助你更好地组织 .NET 项目架构!
出处:http://www.cnblogs.com/lightsong/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。