如何仅为ICommand<>类型注册MediatR请求预处理器?
问题:如何在MediatR+Autofac中配置仅触发于ICommand<>的请求预处理器
我最近在CQRS架构的项目里折腾MediatR管道行为和Autofac依赖注入,想配置一个仅针对命令(ICommand<>)生效的请求预处理器,不想让它对所有IRequest<>类型(包括查询、事件)都触发。
背景与当前正常运行的配置
目前我已经能让通用预处理器对所有请求生效,相关Autofac配置如下:
// 注册MediatR的管道行为 builder.RegisterGeneric(typeof(RequestPostProcessorBehavior<,>)) .As(typeof(IPipelineBehavior<,>)); builder.RegisterGeneric(typeof(RequestPreProcessorBehavior<,>)) .As(typeof(IPipelineBehavior<,>)); // 对所有请求生效的通用预处理器(正常工作) builder.RegisterGeneric(typeof(GenericRequestPreProcessor<>)) .As(typeof(IRequestPreProcessor<>)); // 这是我要改造的命令预处理器,现在对所有请求生效,但我需要限制它只处理命令 builder.RegisterGeneric(typeof(MyCommandPreProcessor<>)) .As(typeof(IRequestPreProcessor<>));
我试过的失败方案
为了让MyCommandPreProcessor只处理命令,我试了几种注册方式,但都没成功:
- 尝试绑定未绑定泛型的服务类型
builder.RegisterGeneric(typeof(MyCommandPreProcessor<>)) .As(typeof(IRequestPreProcessor<ICommand<>>));
报错:Intellisense提示
Unexpected use of an unbound generic,不能用未绑定的泛型作为服务类型
- 非泛型处理器绑定未绑定泛型
builder.RegisterType(typeof(MyCommandPreProcessor)) .As(typeof(IRequestPreProcessor<ICommand<>>));
同样触发未绑定泛型的错误
- 绑定到具体封闭泛型
builder.RegisterType(typeof(MyCommandPreProcessor)) .As(typeof(IRequestPreProcessor<ICommand<CommonResult>>));
编译没问题,但
MyCommandPreProcessor完全不会触发
我的预处理器实现(两种版本都试过)
泛型版本
public class MyCommandPreProcessor<TRequest> : IRequestPreProcessor<TRequest> { public Task Process(TRequest request, CancellationToken cancellationToken) { Debug.WriteLine("***** MYCOMMAND PREPROCESSOR CALLED *****"); return Task.CompletedTask; } }
非泛型版本
public class MyCommandPreProcessor : IRequestPreProcessor<IRequest<ICommonResponse>> { public Task Process(IRequest<ICommonResponse> request, CancellationToken cancellationToken) { Debug.WriteLine("***** MYCOMMAND PREPROCESSOR CALLED *****"); return Task.CompletedTask; } }
项目的类型继承结构
我的CQRS类型层级是这样的:
- 请求接口:
IMediatR.IRequest<TResponse>←IMessage<TResponse>←ICommand<TResponse>(具体实现比如MyCommand : ICommand<CommonResponse>);同时IMessage<TResponse>也派生IQuery<TResponse>(具体实现MyQuery : IQuery<CommonResponse>) - 处理器接口:
IMediatR.IRequestHandler<in TRequest,TResponse>←IMessageHandler<in TRequest,TResponse>←ICommandHandler<in TRequest,TResponse>/IQueryHandler<in TRequest,TResponse>
核心疑问
到底该怎么注册这个预处理器,才能让它只对实现了ICommand<>的请求触发,自动忽略查询等其他IRequest<>类型?
内容的提问来源于stack exchange,提问作者platypusjh
相关产品推荐
相关产品推荐

