返回

MediatR在.NET项目中的应用:提升ASP.NET Core架构解耦与可维护性的实践指南

2026-06-20 MediatR .NET ASP.NET Core 262 0

什么是MediatR?

MediatR 是.NET生态中非常流行的中介者模式(Mediator Pattern)实现库,它能够帮助开发者降低对象之间的耦合度,使系统架构更加清晰。在ASP.NET Core项目中,控制器通常不再直接依赖多个Service,而是通过IMediator发送请求,由对应的Handler进行处理。

简单来说,MediatR解决的是:

  • Controller过于臃肿
  • Service之间相互调用复杂
  • 业务逻辑难以维护
  • 单元测试困难
  • 模块职责不清晰

目前,MediatR已经成为许多Clean Architecture和CQRS项目中的标准组件之一。大量企业级.NET项目都将其作为核心架构方案的一部分。

为什么.NET项目需要MediatR?

传统ASP.NET Core项目通常是这样的调用方式:

Controller
    ↓
Service
    ↓
Repository

随着业务增长,一个控制器可能需要注入:

public class OrderController
{
    private readonly IOrderService _orderService;
    private readonly IUserService _userService;
    private readonly IEmailService _emailService;
    private readonly ILogService _logService;
}

这种设计容易出现:

  • 控制器依赖过多
  • 服务层职责混乱
  • 模块之间强耦合
  • 修改功能影响范围较大

引入MediatR后:

Controller
    ↓
Mediator
    ↓
Handler

控制器只依赖一个IMediator:

public class OrderController : ControllerBase
{
    private readonly IMediator _mediator;

    public OrderController(IMediator mediator)
    {
        _mediator = mediator;
    }
}

这样可以显著降低代码耦合度。

在ASP.NET Core中安装MediatR

安装NuGet包:

dotnet add package MediatR
dotnet add package MediatR.Extensions.Microsoft.DependencyInjection

注册服务:

builder.Services.AddMediatR(cfg =>
{
    cfg.RegisterServicesFromAssembly(typeof(Program).Assembly);
});

之后即可在整个项目中使用IMediator。

Command与Query的应用

MediatR最常见的使用方式就是结合CQRS。

Query(查询)

public record GetUserQuery(int Id) : IRequest<UserDto>;

Handler:

public class GetUserQueryHandler
    : IRequestHandler<GetUserQuery, UserDto>
{
    public async Task<UserDto> Handle(
        GetUserQuery request,
        CancellationToken cancellationToken)
    {
        return await _repository.GetAsync(request.Id);
    }
}

调用:

var user = await _mediator.Send(
    new GetUserQuery(id));

Command(命令)

public record CreateUserCommand(
    string Name,
    string Email)
    : IRequest<int>;

Handler:

public class CreateUserCommandHandler
    : IRequestHandler<CreateUserCommand, int>
{
    public async Task<int> Handle(
        CreateUserCommand request,
        CancellationToken cancellationToken)
    {
        var user = new User
        {
            Name = request.Name,
            Email = request.Email
        };

        await _repository.AddAsync(user);

        return user.Id;
    }
}

CQRS将读写操作分离,使业务逻辑更加清晰,也更有利于系统扩展。

Notification事件通知

MediatR不仅支持请求响应,还支持发布订阅模式。

定义通知:

public record UserCreatedNotification(int UserId)
    : INotification;

事件处理:

public class SendEmailHandler
    : INotificationHandler<UserCreatedNotification>
{
    public Task Handle(
        UserCreatedNotification notification,
        CancellationToken cancellationToken)
    {
        // 发送邮件
    }
}

发布事件:

await _mediator.Publish(
    new UserCreatedNotification(user.Id));

一个事件可以拥有多个处理器:

  • 发送邮件
  • 写入日志
  • 发送短信
  • 更新缓存
  • 推送消息

这样可以避免大量Service之间的相互调用。

Pipeline Behavior的高级应用

Pipeline Behavior类似ASP.NET Core中的中间件。

常见应用:

参数验证

public class ValidationBehavior<TRequest, TResponse>
    : IPipelineBehavior<TRequest, TResponse>
{
    public async Task<TResponse> Handle(
        TRequest request,
        RequestHandlerDelegate<TResponse> next,
        CancellationToken cancellationToken)
    {
        // 参数验证

        return await next();
    }
}

日志记录

_logger.LogInformation(
    "Handling {RequestName}",
    typeof(TRequest).Name);

性能监控

统计每个Handler执行时间。

缓存处理

对于查询请求可以统一增加缓存逻辑。

Pipeline Behavior已经成为MediatR最受欢迎的特性之一。很多大型项目都会利用它实现:

  • 日志
  • 缓存
  • 权限
  • 审计
  • 验证
  • 事务

等横切关注点。

MediatR结合Clean Architecture

典型目录结构:

Application
│
├── Commands
├── Queries
├── Handlers
├── Behaviors
└── Events

Domain

Infrastructure

WebApi

Controller:

[HttpGet("{id}")]
public async Task<UserDto> Get(int id)
{
    return await _mediator.Send(
        new GetUserQuery(id));
}

业务逻辑全部放入Application层。

这种设计具有:

  • 高内聚
  • 低耦合
  • 易测试
  • 易维护
  • 易扩展

目前大量Clean Architecture项目都采用这种模式。

MediatR的优点

  • 降低依赖:控制器只依赖IMediator。
  • 职责明确:一个请求对应一个Handler。
  • 方便测试:Handler可以单独测试。
  • 支持CQRS:天然适合读写分离。
  • 扩展能力强:支持通知、行为管道、事件。
  • 架构清晰:非常适合大型项目。

MediatR的缺点

虽然MediatR十分优秀,但并不是所有项目都需要它。

对于简单CRUD系统,Controller → Service → Repository 可能已经足够。

如果项目规模较小,强行引入大量Command和Query,可能导致:

  • 文件数量爆炸
  • Handler过多
  • 学习成本增加
  • 开发效率下降

社区中也有不少开发者认为,小型项目没有必要使用完整CQRS。MediatR本身并不强制必须配合CQRS使用,可以仅用于解耦控制器和业务逻辑。

使用建议

推荐使用MediatR的场景:

  • 企业级系统
  • 微服务项目
  • 大型后台系统
  • Clean Architecture项目
  • CQRS架构
  • 多团队协作项目

不建议使用的场景:

  • 简单CRUD网站
  • 小型管理后台
  • 原型项目
  • 个人练手项目

选择技术方案时,应根据业务复杂度进行判断,而不是盲目追求架构设计。

总结

MediatR已经成为现代.NET开发中非常重要的架构工具。它通过中介者模式降低系统耦合,使Controller更加轻量,业务逻辑更加独立,并且能够很好地支持CQRS、Clean Architecture以及事件驱动设计。

对于中大型ASP.NET Core项目而言,MediatR能够显著提升系统的可维护性和扩展能力。而对于简单业务系统,则需要权衡其带来的复杂度。合理地使用MediatR,才能真正发挥它在现代.NET架构中的价值。

顶部