Mediatr 9中注册含三个类型参数的Pipeline Behavior未触发问题
Mediatr 9 泛型管道行为注册后未触发问题
问题场景
使用Mediatr 9时,注册了带额外类型参数的Pipeline Behavior,代码编译正常,但管道未被触发。
相关代码签名
管道行为签名
public class EnvelopeValidationHandlerAsync<TRequest, TResponse, TRequestItem> : IPipelineBehavior<TRequest, TResponse> where TRequest : RequestEnvelope<TRequestItem, Response<TResponse>> where TRequestItem : RequestItem, new() where TResponse: class
请求相关签名
public class CreatePatientRequestEnvelope: RequestEnvelope<CreatePatientRequest, Response<PatientResponse>> public class CreatePatientRequest : RequestItem
请求信封基类
public class RequestEnvelope<TRequestItem, TResponse> : Request<TResponse>, IRequestEnvelope<TRequestItem, TResponse> where TRequestItem : IRequestItem, new()
注册代码(Autofac)
containerBuilder.RegisterGeneric(typeof(EnvelopeValidationHandlerAsync<,,>)).As(typeof(IPipelineBehavior<,>));
问题原因与解决方案
问题原因
Autofac处理泛型注册时,无法自动推断管道行为的第三个泛型参数TRequestItem。Mediatr解析IPipelineBehavior<TRequest, TResponse>时,仅能提供TRequest和TResponse两个类型参数,你的管道行为需要第三个参数,但Autofac无法从TRequest中自动提取出TRequestItem完成泛型实例化,导致管道行为未被正确注入,因此不会被触发。
解决方案
有两种可行的解决方式:
方案1:简化管道行为的泛型参数
移除第三个泛型参数TRequestItem,改为从TRequest的泛型参数中通过反射获取:
public class EnvelopeValidationHandlerAsync<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> where TRequest : RequestEnvelope<RequestItem, Response<TResponse>> where TResponse: class { public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken) { // 获取TRequest对应的TRequestItem实际类型 var requestItemType = typeof(TRequest).GetGenericArguments()[0]; // 执行你的验证逻辑... return await next(); } }
对应的注册代码简化为:
containerBuilder.RegisterGeneric(typeof(EnvelopeValidationHandlerAsync<,>)).As(typeof(IPipelineBehavior<,>));
方案2:使用Autofac工厂手动解析泛型参数
通过注册工厂方法,手动从TRequest中提取TRequestItem类型,创建管道行为实例:
containerBuilder.RegisterGeneric((context, types) => { var tRequest = types[0]; var tResponse = types[1]; // 从RequestEnvelope的泛型参数中获取TRequestItem var tRequestItem = tRequest.GetGenericArguments()[0]; // 构造泛型管道行为类型并创建实例 var handlerType = typeof(EnvelopeValidationHandlerAsync<,,>).MakeGenericType(tRequest, tResponse, tRequestItem); return Activator.CreateInstance(handlerType); }).As(typeof(IPipelineBehavior<,>));
这样Autofac就能正确创建管道行为实例,Mediatr处理请求时会触发该管道。
内容的提问来源于stack exchange,提问作者adova
相关产品推荐
相关产品推荐

