Skip to content
bitzorcas
中EN

Guide

纯函数式入站校验:IRequestRule 与防腐设计

告别低效脆弱的业务异常!深入解析 BitzOrcas.Modern 纯函数式前置校验体系,掌握 IRequestRule 规则声明、ValidationPipelineBehavior 管道拦截与结构化错误码映射。

Last updated

在传统的后端接口开发中,参数校验往往存在三大通病:

  1. 用业务异常做流控(Exception as Flow Control):只要参数不合法就 throw new ValidationException("..."),在高并发下频繁创建异常栈导致严重的 CPU 损耗;
  2. 校验代码污染 Handler:在业务用例开头写满密密麻麻的 if (string.IsNullOrEmpty(...)) return ...,导致核心业务逻辑被噪声淹没;
  3. 前端难以解析错误:返回随意的中文错误文本,前端无法针对特定的表单字段做精准的高亮提示。

BitzOrcas.Modern 采用基于 IRequestRule<TRequest> 的纯函数校验体系:校验逻辑与 Handler 彻底解耦,在进入事务与数据库之前由 ValidationPipelineBehavior 毫秒级完成拦截,并返回结构化强类型 Result。

纯函数校验生命周期全景

任一规则失败全部通过

1. 入站请求 (Command / Query)

2. ValidationPipelineBehavior

3. 执行关联的 IRequestRule 规则集 (纯函数零副作用)

4. 短路返回 Result.Failure(ValidationError)

5. 进入真实业务 Handler


第一步:编写纯函数规则 IRequestRule

每个规则类实现 IRequestRule<TRequest>,只负责针对输入契约进行不可变量评估:

CreateCustomerCommandRules.cs: 声明入站校验规则
using BitzOrcas.Application.Abstractions.Validation;
using BitzOrcas.Domain.Results;
using BitzOrcas.Customer.Contracts.Commands;
namespace BitzOrcas.Customer.Application.Rules;
public static class CustomerErrors
{
public static readonly Error NameRequired =
Error.Validation("Customer.NameRequired", "客户名称不能为空。");
public static readonly Error NameTooLong =
Error.Validation("Customer.NameTooLong", "客户名称长度不能超过 100 个字符。");
}
// 校验客户名称不为空且长度合规
public sealed class CustomerNameMustBeValidRule : IRequestRule<CreateCustomerCommand>
{
public ValueTask<Result> ValidateAsync(CreateCustomerCommand request, CancellationToken ct)
{
// 1. 纯内存逻辑判断,零外部 I/O 副作用
if (string.IsNullOrWhiteSpace(request.CustomerName))
{
return ValueTask.FromResult(Result.Failure(CustomerErrors.NameRequired));
}
if (request.CustomerName.Length > 100)
{
return ValueTask.FromResult(Result.Failure(CustomerErrors.NameTooLong));
}
// 2. 规则校验通过
return ValueTask.FromResult(Result.Success());
}
}

第二步:管道层全自动执行与零代码侵入

框架在 DI 启动时通过程序集扫描自动注册所有 IRequestRule<T>。当请求进入时,ValidationPipelineBehavior 自动拉起所有匹配的规则顺序执行:

ValidationPipelineBehavior.cs: 自动拦截逻辑
public sealed class ValidationPipelineBehavior<TRequest, TResponse>(
IEnumerable<IRequestRule<TRequest>> rules) : IPipelineBehavior<TRequest, TResponse>
{
public async ValueTask<TResponse> Handle(
TRequest message,
CancellationToken cancellationToken,
MessageHandlerDelegate<TRequest, TResponse> next)
{
// 1. 遍历所有注册的校验规则
foreach (var rule in rules)
{
var result = await rule.ValidateAsync(message, cancellationToken);
if (result.IsFailure)
{
// 2. 一旦有规则失败,立即短路返回强类型错误,绝不抛出异常
return (TResponse)(object)result;
}
}
// 3. 全部校验通过,放行进入业务 Handler
return await next(message, cancellationToken);
}
}

总结

BitzOrcas 的入站校验体系让业务代码保持纯净:

  • 纯函数零开销:无异常抛出,GC 零压力;
  • 业务代码解耦:Handler 只专注核心领域流转;
  • 强类型错误码:前端可基于 ErrorCode 实现精准的表单多语言错误映射。

100%

滚轮或按钮缩放 · 放大后拖动画面 · 双击切换 100% / 200%