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

MediatR中自定义泛型PipelineBehavior(Behavior_2)未触发的问题及实现需求咨询

MediatR中自定义泛型PipelineBehavior(Behavior_2)未触发的问题及实现需求咨询

我来帮你分析和解决这个问题,你核心想让类似Behavior_2的PipelineBehavior正常触发,并且能在验证不通过时提前返回失败的QueryResult对吧?咱们先拆解问题原因,再给出可行的解决方案。

为什么Behavior_2没被触发?

问题出在MediatR对开放泛型PipelineBehavior的匹配规则上。你定义的Behavior_2<TQuery, TResult>实现的是IPipelineBehavior<TQuery, QueryResult<TResult>>,但MediatR在匹配行为时,要求行为的第二个泛型参数必须直接对应请求的返回类型(也就是IRequest<TResponse>里的TResponse)。

你的PingQuery实现了IQuery<Pong>,而IQuery<TResult>继承自IRequest<QueryResult<TResult>>,所以PingQuery对应的返回类型是QueryResult<Pong>。但Behavior_2的第二个泛型参数是QueryResult<TResult>,这相当于让MediatR去匹配一个“泛型嵌套泛型”的返回类型,它没法自动推断出TResult对应的实际类型是Pong,因此就跳过了这个行为。

解决方案:调整Behavior_2的泛型约束

我们需要修改Behavior_2的泛型定义,让它能精准匹配返回类型为QueryResult<TResult>的请求。修改后的代码如下:

public class Behavior_2<TRequest, TResult> : IPipelineBehavior<TRequest, QueryResult<TResult>>
    where TRequest : IRequest<QueryResult<TResult>>
{
    public async Task<QueryResult<TResult>> Handle(TRequest request, RequestHandlerDelegate<QueryResult<TResult>> next, CancellationToken cancellationToken)
    {
        Console.WriteLine($"'{GetType()}' is processing '{request.GetType()}'");
        
        if (!DoSomeValidation())
        {
            // 验证不通过时直接返回失败的QueryResult,跳过后续handler执行
            return new QueryResult<TResult> 
            { 
                Succeeded = false, 
                Error = "Validation failed" 
            };
        }

        var result = await next(cancellationToken);
        return result;
    }

    private static bool DoSomeValidation() => false;
}

关键修改点说明

  • 泛型参数调整为TRequest和TResult,并给TRequest加上IRequest<QueryResult<TResult>>的约束,完美匹配你定义的IQuery<TResult>(因为IQuery<TResult>本身就继承自IRequest<QueryResult<TResult>>)
  • 现在MediatR可以清晰识别到所有返回QueryResult<TResult>的请求,自然会触发这个行为

额外优化:只针对IQuery类型的请求生效

如果你希望这个行为只处理实现了IQuery<TResult>的请求,而不是所有返回QueryResult<TResult>的IRequest,可以把约束改成更精准的:

where TRequest : IQuery<TResult>

注册代码无需修改

你原来的服务注册代码保持不变即可:

services.AddMediatR(configuration => {
    configuration.RegisterServicesFromAssembly(typeof(Program).Assembly);
    configuration.AddOpenBehavior(typeof(Behavior_1<,>));
    configuration.AddOpenBehavior(typeof(Behavior_2<,>));
});

现在重新测试发送PingQuery,Behavior_2就会正常触发,并且在验证失败时提前返回错误结果,不会执行后续的PingQueryHandler。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 10:35:28