Razor Page项目如何通过字典动态注册CQRS验证器服务?
实现FluentValidation验证器的动态注册(替代手动逐个添加)
当然可以,这种方式能大幅减少重复的手动注册代码,尤其当项目里的CQRS命令/查询数量较多时,维护成本会低很多。下面提供两种实现思路:
一、手动维护映射字典(你提到的方案)
先创建一个字典存储命令/查询与对应验证器的类型映射,再遍历字典完成批量注册:
代码示例
// 在Program.cs中定义映射字典 var validatorMappings = new Dictionary<Type, Type> { { typeof(GetPhonesQuery), typeof(GetPhonesQueryValidator) }, { typeof(CreatePhoneCommand), typeof(CreatePhoneCommandValidator) }, // 后续新增命令/查询时,直接在此处添加映射关系即可 }; // 遍历字典注册服务 foreach (var mapping in validatorMappings) { var targetType = mapping.Key; var validatorType = mapping.Value; // 构造IValidator<T>的泛型接口类型 var validatorInterface = typeof(IValidator<>).MakeGenericType(targetType); // 注册Scoped服务 builder.Services.AddScoped(validatorInterface, validatorType); }
二、程序集自动扫描(更推荐)
如果不想每次新增命令/查询都手动修改字典,可以通过反射扫描程序集,自动发现所有实现IValidator<T>的验证器并完成注册:
代码示例
// 在Program.cs中添加以下代码 // 获取验证器所在的程序集(这里以GetPhonesQueryValidator所在程序集为例,可根据实际情况调整) var targetAssembly = typeof(GetPhonesQueryValidator).Assembly; // 扫描所有符合条件的验证器类型 var validators = targetAssembly.GetTypes() .Where(t => !t.IsAbstract && !t.IsInterface) // 排除抽象类和接口 .Select(t => new { ValidatorType = t, // 获取验证器对应的命令/查询类型(即IValidator<T>中的T) CommandOrQueryType = t.GetInterfaces() .FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IValidator<>))? .GetGenericArguments()[0] }) .Where(item => item.CommandOrQueryType != null); // 过滤掉未实现IValidator<T>的类型 // 批量注册验证器 foreach (var item in validators) { var validatorInterface = typeof(IValidator<>).MakeGenericType(item.CommandOrQueryType); builder.Services.AddScoped(validatorInterface, item.ValidatorType); }
优势说明
程序集扫描的方式更省心:新增命令/查询及其对应验证器后,只要验证器正确实现IValidator<T>接口,无需修改注册代码,系统会自动识别并完成服务注册,避免了手动维护字典可能出现的遗漏或错误。
内容的提问来源于stack exchange,提问作者J003_
相关产品推荐
相关产品推荐

