基于CQRS+洋葱架构的.NET项目FluentValidation集成配置困惑
.NET CQRS+洋葱架构下集成FluentValidation的正确配置指导
问题概述
在CQRS+洋葱架构的.NET项目中,需要通过过滤器集成FluentValidation:
- 应用层已实现
CreateBookValidator(对应VM_Create_Book的验证规则) - 基础设施层实现了
ValidationFilter用于捕获验证错误并返回标准化响应 - 原写法中
AddFluentValidation()已被弃用,现有服务注册配置混乱,需要梳理优化
配置修正步骤
1. 统一应用层的服务注册(符合洋葱架构职责)
将FluentValidation的核心注册逻辑移至应用层的ServiceRegistiration类,保持分层职责清晰:
public static class ServiceRegistiration { public static void AddApplicationService(this IServiceCollection collection) { collection.AddMediatR(typeof(ServiceRegistiration)); // 注册FluentValidation自动验证机制 collection.AddFluentValidationAutoValidation(); // 注册客户端验证适配器(如需支持前端验证) collection.AddFluentValidationClientsideAdapters(); // 自动扫描应用层所有验证器,无需手动逐个注册 collection.AddValidatorsFromAssemblyContaining<CreateBookValidator>(); collection.AddHttpClient(); } }
说明:
AddValidatorsFromAssemblyContaining<CreateBookValidator>()会自动扫描并注册该程序集下所有继承AbstractValidator<T>的验证器,替代手动的AddScoped<IValidator<VM_Create_Book>, CreateBookValidator>(),减少重复代码- 应用层负责自身依赖(包括验证器)的注册,符合洋葱架构"内层不依赖外层"的原则
2. 简化Program.cs配置
移除Program.cs中重复的FluentValidation注册代码,仅保留控制器和过滤器配置:
var builder = WebApplication.CreateBuilder(args); builder.Services.AddPersistenceServices(); builder.Services.AddApplicationService(); // 注册控制器并添加自定义验证过滤器 builder.Services.AddControllers(options => { options.Filters.Add<ValidationFilter>(); }); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.MapControllers(); app.Run();
3. 验证现有ValidationFilter的有效性
你的ValidationFilter逻辑无需修改:FluentValidationAutoValidation会自动执行验证规则,并将错误写入ModelState,过滤器只需在ModelState无效时返回标准化的BadRequest响应即可:
public class ValidationFilter:IAsyncActionFilter { public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { if (!context.ModelState.IsValid) { var errors = context.ModelState .Where(x => x.Value.Errors.Any()) .ToDictionary(e => e.Key, e => e.Value.Errors.Select(e => e.ErrorMessage)) .ToArray(); context.Result = new BadRequestObjectResult(errors); return; } await next(); } }
关键注意事项
- 确保
CreateBookValidator正确继承AbstractValidator<VM_Create_Book>,示例:public class CreateBookValidator : AbstractValidator<VM_Create_Book> { public CreateBookValidator() { RuleFor(x => x.Title).NotEmpty().MaximumLength(100); RuleFor(x => x.Price).GreaterThan(0); // 其他业务验证规则 } } - 基础设施层的
ValidationFilter属于表现层/基础设施层范畴,符合洋葱架构分层逻辑,无需调整位置 - 避免重复注册验证器(手动单个注册和自动扫描二选一),防止服务注入冲突
内容的提问来源于stack exchange,提问作者mixail sakaşvil
相关产品推荐
相关产品推荐

