在MVC,EF,LINQ环境里,我们经常会用到DataModel(DO)和viewmodel(VO),可能对于它们的属性校验我们会采用特性的方式,当然这很直观,就连微软的DEMO也是如些,一般是这样的代码
/// <summary>/// 机构ID/// </summary>[displayName(机构ID)]public int AgentId { get; set; }/// <summary>/// 机构名称/// </summary>[displayName(机构名称)] [MaxLength(128)]public string AgentName { get; set; }/// <summary>/// 机构负责人/// </summary>[displayName(机构负责人)] [MaxLength(128)]public string AgentUser { get; set; }
而这种设计方式给我们以后的维护带来很多问题,具体大叔总结一下:
与数据实体混在一起,不利用扩展,更新实体你加的特性可能会丢失
如果有多个VO,那么你需要把它加到具体的VO上,因为DO的语义可能不太明确
不方便迁移,它与ModelState耦合太高
从面向对象的角度来看,它的职责太单一,引起变因太多
综上所述,FluentValidation就诞生了!
nuget上去安装它:install-package FluentValidation
你的一个实体类,可以添加多个检验类,这相当于可以有多种检验类去装饰一个实体类,我觉得挺好!
public class createuserEventValidator : AbstractValidator<createuserEvent>{public createuserEventValidator() { RuleFor(command => command.UserName).NotEmpty().Length(5, 20).WithMessage(用户名升序为5-20字符!); RuleFor(command => command.Email).NotEmpty().EmailAddress().WithMessage(不是有效的Email!); RuleFor(command => command.BirthDay).NotEmpty().Must(i => i < DateTime.Now).WithMessage(你的年紀太小了!); } }
使用时,可以通过IsValid,Errors等属性拿到你需要的信息,当然,你也可以把它在命令事件,领域事件上用一下,比如做个验证的装饰器,哪些处理程序要用校验,就通过这个装饰器装饰一下就行了,挺优雅!
BusManager.Instance.Subscribe( ValidatorDecorator<createuserEvent>( UserEventHandler(), BusManager.Instance.Subscribe( LoggerDecorator<createuserEvent>( createuserEvent { UserName = });
/// <summary>/// 验证装饰器/// </summary>/// <typeparam name=TEvent></typeparam> [Serializable]public class ValidatorDecorator<TEvent> : IBusHandler<TEvent>where TEvent : IBusData {/// <summary>/// 要被装饰的处理程序/// </summary>private readonly IBusHandler<TEvent> _inner;/// <summary>/// 校验装饰器集合/// </summary>private readonly IValidator<TEvent>[] _validators;/// <summary>/// 初始化/// </summary>/// <param name=inner>要被装饰的处理程序</param>/// <param name=validators>装饰器</param>public ValidatorDecorator(IBusHandler<TEvent> inner, params IValidator<TEvent>[] validators) { _inner = inner; _validators = validators; }public void Handle(TEvent evt) {var failures = _validators .Select(v => v.Validate(evt)) .SelectMany(result => result.Errors) .Where(error => error != null) .ToList();if (failures.Any()) {throw new ValidationException(实体校验失败, failures); } _inner.Handle(evt); } }
对于一种知识的学习与理解是需要一些理论基础的,大家可以多看看设计模块,算法导论,.netCLR等书籍!
感谢各位的阅读!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。