如何注册支持泛型BaseResponse的约束MediatR管道行为至DI容器
解决方案
1. 定义非泛型基础接口
先创建一个非泛型的IBaseResponse接口,提取原BaseResponse中无需泛型的公共属性(如请求状态、错误信息等):
public interface IBaseResponse { bool IsSuccess { get; set; } string ErrorMessage { get; set; } // 其他公共非泛型属性按需添加 }
2. 实现泛型BaseResponse类
让泛型版本的BaseResponse<T>实现上述非泛型接口:
public class BaseResponse<T> : IBaseResponse { public bool IsSuccess { get; set; } public string ErrorMessage { get; set; } public T Data { get; set; } // 泛型结果属性 }
3. 修改行为类的泛型约束
保持行为类的两个泛型参数不变,仅调整约束条件,让TResponse继承自IBaseResponse:
public class FailFastRequestBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> where TRequest : IRequest<TResponse> where TResponse : IBaseResponse, new() // 若需创建实例则添加new()约束
4. 保留原有DI注册方式
DI注册代码无需修改,仍使用开放泛型注册:
services.AddScoped( typeof(IPipelineBehavior<,>), typeof(FailFastRequestBehavior<,>));
5. 行为内处理泛型响应(可选)
如果行为需要访问BaseResponse<T>的泛型Data属性,可通过类型判断和转换实现:
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken) { // 示例:请求校验逻辑 if (!ValidateRequest(request)) { var response = Activator.CreateInstance<TResponse>(); response.IsSuccess = false; response.ErrorMessage = "参数校验失败"; // 针对泛型Data属性的操作 if (response is BaseResponse<object> genericResp) { genericResp.Data = default; // 或设置自定义错误数据 } return response; } return await next(); }
最终命令示例
现在你的命令可以正常使用泛型响应:
public class Command : IRequest<BaseResponse<MyObject>> { // 命令属性按需定义 }
内容的提问来源于stack exchange,提问作者rbasniak
相关产品推荐
相关产品推荐

