You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET6中MediatR多个Pipeline Behavior执行顺序及优先级设置方法

MediatR多管道行为执行顺序与优先级配置解答

一、当前注册方式的实际执行顺序

MediatR的IPipelineBehavior管道执行逻辑和ASP.NET Core中间件完全一致,采用嵌套式俄罗斯套娃模型,默认执行顺序完全由服务注册到DI容器的顺序决定:

  • 你当前代码中四个管道的注册顺序为:UnhandledExceptionBehaviour→AuthorizationBehaviour→ValidationBehaviour→PerformanceBehaviour
  • 请求流入阶段(调用next()委托前的前置逻辑)严格按照注册顺序执行:先进入UnhandledExceptionBehaviour,再到AuthorizationBehaviour做权限校验,再到ValidationBehaviour做参数校验,再到PerformanceBehaviour,最后才会执行具体CommandHandler的业务逻辑
  • 响应返回阶段(调用next()委托后的后置逻辑)执行顺序完全反转:Handler执行完成后,先回到PerformanceBehaviour执行后置逻辑,再依次返回ValidationBehaviour、AuthorizationBehaviour,最后回到UnhandledExceptionBehaviour,结果才会返回给上游调用方

注意:你当前的注册顺序存在不符合常规范式的问题:PerformanceBehaviour作为最后一个注册的管道,仅包裹了CommandHandler本身,统计到的耗时只会包含Handler的执行时间,不会覆盖授权、参数校验环节的耗时,如果需要统计全链路处理耗时,这个顺序需要调整。而UnhandledExceptionBehaviour放在第一个注册是正确的,作为最外层管道可以捕获后续所有管道和Handler抛出的异常。

二、管道行为执行优先级的设置方式

MediatR本身没有内置独立的优先级配置API,默认完全以DI注册顺序为执行依据,常用的优先级设置方案有两种:

方案1:直接调整注册顺序(最推荐,无额外侵入)

直接调整IPipelineBehavior<,>的注册代码先后位置即可,需要越先执行(越外层)的管道,放在越靠前的位置注册。
常规业务场景下的推荐注册顺序(从先到后)参考:

services.AddMediatR(Assembly.GetExecutingAssembly());
// 1. 全局异常处理管道(最外层,捕获所有内层管道、Handler抛出的异常)
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(UnhandledExceptionBehaviour<,>));
// 2. 全链路监控/日志管道(包裹后续所有业务相关管道,统计全链路耗时、打印请求日志)
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(PerformanceBehaviour<,>));
// 3. 授权校验管道
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(AuthorizationBehaviour<,>));
// 4. 参数校验管道
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehaviour<,>));
// 最后执行具体CommandHandler

方案2:自定义特性标记+自动排序(适合多模块自动注册场景)

如果你的项目存在分模块自动注册管道、不方便手动调整注册顺序的情况,可以通过自定义优先级特性+服务重排的方式统一控制顺序,实现步骤如下:

  1. 定义优先级标记特性
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class PipelineOrderAttribute : Attribute
{
    /// <summary>
    /// 执行顺序,数值越小越先执行(越靠近管道外层)
    /// </summary>
    public int Order { get; }
    public PipelineOrderAttribute(int order) => Order = order;
}
  1. 给自定义管道标记顺序值
[PipelineOrder(1)]
public class UnhandledExceptionBehaviour<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
{
    // 管道实现逻辑
}

[PipelineOrder(2)]
public class PerformanceBehaviour<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
{
    // 管道实现逻辑
}
// 其他管道同理标记对应Order值即可
  1. 编写服务排序扩展方法,在所有管道注册完成后调用
public static class MediatRServiceExtensions
{
    public static IServiceCollection SortMediatRPipelines(this IServiceCollection services)
    {
        // 查找所有IPipelineBehavior的服务注册
        var pipelineRegistrations = services
            .Where(s => s.ServiceType.IsGenericType 
                        && s.ServiceType.GetGenericTypeDefinition() == typeof(IPipelineBehavior<,>))
            .ToList();
        // 移除原有注册
        foreach (var reg in pipelineRegistrations)
        {
            services.Remove(reg);
        }
        // 按照Order值从小到大排序,未标记特性的管道默认排到最后
        var sortedRegistrations = pipelineRegistrations.OrderBy(reg =>
        {
            var implType = reg.ImplementationType;
            if (implType == null) return int.MaxValue;
            var orderAttr = implType.GetCustomAttribute<PipelineOrderAttribute>();
            return orderAttr?.Order ?? int.MaxValue;
        });
        // 按排序后的顺序重新注册
        foreach (var reg in sortedRegistrations)
        {
            services.Add(reg);
        }
        return services;
    }
}
  1. 在ConfigureServices中调用扩展方法
services.AddMediatR(Assembly.GetExecutingAssembly());
// 此处手动/自动注册管道时无需关心顺序
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehaviour<,>));
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(UnhandledExceptionBehaviour<,>));
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(PerformanceBehaviour<,>));
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(AuthorizationBehaviour<,>));
// 最后调用排序方法,自动按照标记的优先级重排
services.SortMediatRPipelines();

内容的提问来源于stack exchange,提问作者Alireza Ahmadi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 03:21:40