如何为MediatR指定RequestHandler自定义专属behaviour列表
MediatR 为指定请求处理器配置专属行为的解决方案
可以实现该需求,以下是3种主流实现方案:
方案1:按请求类型泛型精准注册(推荐)
MediatR的管道行为默认注册开放泛型时会全局生效,你可以删除全局的开放泛型注册,改为针对具体请求类型注册封闭泛型行为,绑定关系完全在DI注册阶段配置,无需修改行为代码。
示例注册代码:
// 仅为 Request1 注册指定行为 services.AddTransient<IPipelineBehavior<Request1, Response1>, MyBehavior1<Request1, Response1>>(); services.AddTransient<IPipelineBehavior<Request1, Response1>, MyBehaviour2<Request1, Response1>>(); // 仅为 Request2 注册指定行为 services.AddTransient<IPipelineBehavior<Request2, Response2>, MyBehavior1<Request2, Response2>>(); services.AddTransient<IPipelineBehavior<Request2, Response2>, MyBehavior3<Request2, Response2>>();
注意:务必删除之前注册的IPipelineBehavior<,>开放泛型行为,否则全局注册的行为仍会对所有请求生效
方案2:标记接口过滤
给需要走特定行为的请求添加空的标记接口,在行为内部判断当前请求是否实现了对应标记接口,未实现则直接跳过执行逻辑。
示例代码:
- 定义标记接口
// 标记需要走MyBehaviour2的请求 public interface IUseBehaviour2 {} // 标记需要走MyBehaviour3的请求 public interface IUseBehaviour3 {}
- 给请求类实现对应接口
public class Request1 : IRequest<Response1>, IUseBehaviour2 { // 请求属性 } public class Request2 : IRequest<Response2>, IUseBehaviour3 { // 请求属性 }
- 在行为中添加判断逻辑
// MyBehaviour2 内部示例 public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken) { if (request is not IUseBehaviour2) { // 未实现标记接口,直接跳过当前行为 return await next(); } // 执行MyBehaviour2的业务逻辑 // ... return await next(); }
方案3:特性标记过滤
适合行为数量较多的场景,无需定义大量标记接口,通过特性标注需要启用的行为即可。
示例代码:
- 定义启用行为的特性
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] public class EnableBehaviorAttribute : Attribute { public Type BehaviorType { get; } public EnableBehaviorAttribute(Type behaviorType) => BehaviorType = behaviorType; }
- 给请求类加特性标注
[EnableBehavior(typeof(MyBehaviour2<,>))] public class Request1 : IRequest<Response1> { // 请求属性 } [EnableBehavior(typeof(MyBehavior3<,>))] public class Request2 : IRequest<Response2> { // 请求属性 }
- 在行为中添加判断逻辑
// MyBehaviour2 内部示例 public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken) { var hasAttr = request.GetType() .GetCustomAttributes<EnableBehaviorAttribute>() .Any(a => a.BehaviorType == typeof(MyBehaviour2<,>)); if (!hasAttr) { return await next(); } // 执行MyBehaviour2的业务逻辑 // ... return await next(); }
内容的提问来源于stack exchange,提问作者Dmitriy
相关产品推荐
相关产品推荐

