回到目录

在MVC,EF,LINQ环境里,我们经常会用到DataModel(DO)和ViewModel(VO),可能对于它们的属性校验我们会采用特性的方式,当然这很直观,就连微软的DEMO也是如些,一般是这样的代码

        /// <summary>
/// 机构ID
/// </summary>
[DisplayName("机构ID")]
public int AgentId { get; set; }
/// <summary>
/// 机构名称
/// </summary>
[DisplayName("机构名称")]
[MaxLength()]
public string AgentName { get; set; }
/// <summary>
/// 机构负责人
/// </summary>
[DisplayName("机构负责人")]
[MaxLength()]
public string AgentUser { get; set; }

而这种设计方式给我们以后的维护带来很多问题,具体大叔总结一下:

  1. 与数据实体混在一起,不利用扩展,更新实体你加的特性可能会丢失
  2. 如果有多个VO,那么你需要把它加到具体的VO上,因为DO的语义可能不太明确
  3. 不方便迁移,它与ModelState耦合太高
  4. 从面向对象的角度来看,它的职责太单一,引起变因太多

综上所述,FluentValidation就诞生了!

nuget上去安装它:install-package FluentValidation

你的一个实体类,可以添加多个检验类,这相当于可以有多种检验类去装饰一个实体类,我觉得挺好!

   public class CreateUserEventValidator : AbstractValidator<CreateUserEvent>
{
public CreateUserEventValidator()
{
RuleFor(command => command.UserName).NotEmpty().Length(, ).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(new ValidatorDecorator<CreateUserEvent>(
new UserEventHandler(),
new CreateUserEventValidator()));
//日志-装饰器
BusManager.Instance.Subscribe(new LoggerDecorator<CreateUserEvent>(new UserEventHandler()));
BusManager.Instance.Publish(new CreateUserEvent { UserName = "占占大师5个字" });

装饰器要求你转一个要被装饰的对象和一个装饰器,就可以了。

    /// <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等书籍!

感谢各位的阅读!

回到目录

EF架构~FluentValidation实体检验与实体分离了的更多相关文章

  1. EF架构~为EF DbContext生成的实体添加注释(T5模板应用)

    回到目录 相关文章系列 第八回 EF架构~将数据库注释添加导入到模型实体类中 第二十一回  EF架构~为EF DbContext生成的实体添加注释(T4模板应用) 第二十二回EF架构~为EF DbCo ...

  2. EF架构~为EF DbContext生成的实体添加注释(T5模板应用)(转载)

    转载地址:http://www.newlifex.com/showtopic-1072.aspx 最近新项目要用Entity Framework 6.x,但是我发现从数据库生成模型时没有生成字段的注释 ...

  3. 【转】EF架构~为EF DbContext生成的实体添加注释(T5模板应用)

    嗨,没法说,EF4的TT模版加上注释后,升级到EF5的TT模版后,注释就不通用了,所以,还得再研究一下,然后把操作方法再分享出来,没辙的微软! T4模版可能有些凌乱,这在T5模版里有了不错的改进,但我 ...

  4. EF架构~AutoMapper对象映射工具简化了实体赋值的过程

    回到目录 AutoMapper是一个.NET的对象映射工具,一般地,我们进行面向服务的开发时,都会涉及到DTO的概念,即数据传输对象,而为了减少系统的负载,一般我们不会把整个表的字段作为传输的数据,而 ...

  5. EF架构~通过EF6的DbCommand拦截器来实现数据库读写分离~终结~配置的优化和事务里读写的统一

    回到目录 本讲是通过DbCommand拦截器来实现读写分离的最后一讲,对之前几篇文章做了一个优化,无论是程序可读性还是实用性上都有一个提升,在配置信息这块,去除了字符串方式的拼接,取而代之的是sect ...

  6. ASP.NET Core搭建多层网站架构【5-网站数据库实体设计及映射配置】

    2020/01/29, ASP.NET Core 3.1, VS2019, EntityFrameworkCore 3.1.1, Microsoft.Extensions.Logging.Consol ...

  7. EF架构~基于EF数据层的实现

    回到目录 之前写过关于实现一个完整的EF架构的文章,文章的阅读量也是满大的,自己很欣慰,但是,那篇文章是我2011年写的,所以,技术有些不成熟,所以今天把我的2014年写的EF底层架构公开一下,这个架 ...

  8. EF架构~CodeFirst数据迁移与防数据库删除

    回到目录 本文介绍两个概念,防数据库自动删除,这是由于在code first模式下,当数据实体发生变化时,会对原来数据库进行删除,并将新数据表添加进来,但这对于我们的运营环境数据库,是万万不能接受的, ...

  9. EF架构~过滤导航属性等,拼接SQL字符串

    拼接T-SQL串,并使它具有通用性 好处:与服务器建立一次连接,给服务器发一条SQL命令,即可实现 代码如下: 1 /// <summary> 2 /// 构建Insert语句串 3 // ...

随机推荐

  1. 硬核机器学习干货,手把手教你写KNN!

    机器学习相关概念 人工智能.机器学习和深度学习的关系 在探讨算法之前,我们先来谈一谈什么是机器学习.相信大家都听说过AlphaGo:2016年3月,AlphaGo与围棋世界冠军李世石进行围棋人机大战, ...

  2. Gatsby上手指南 - 让你的静态网站用react来高逼格的写

    注意:Gatsby V2版本安装及使用问题请移步<Gastby V2安装过程中常见问题>,此文较旧,主要针对V1版Gatsby而介绍 前言 一直以来都是用之前比较流行的静态网站生成器Hex ...

  3. C++ 使用 curl 进行 http 请求(GET、POST、Download)的封装

    修改自网路 CommonTools.h /* * CommonTools.h * * Created on: 2018年8月2日 * Author: didi */ #include <iost ...

  4. 错误解决记录------------rhel安装Mysql软件包依赖 mariadb组件

    错误解决记录------------软件包依赖 mariadb组件 错误信息: 错误:软件包:akonadi-mysql-1.9.2-4.el7.x86_64 (@anaconda) 需要:maria ...

  5. 数据分析 大数据之路 六 matplotlib 绘图工具

      散点图 #导入必要的模块 import numpy as np import matplotlib.pyplot as plt #产生测试数据 x = np.arange(1,10) y = x ...

  6. 我的 FPGA 学习历程(07)—— BCD 编码:移位加 3 算法

    2-10 进制码,也称为 BCD 码,它的编码方式则是通过一个 4 位二进制来表示一个 10 进制数,部分十进制对应的 BCD 码如下 十进制数 | BCD 码 13 --> 0001_0011 ...

  7. [CF364D]Ghd

    [CF364D]Ghd 题目大意: 有\(n(n\le10^6)\)个数\(A_{1\sim n}(A_i\le10^{12})\),从中选取\(\lceil\frac n2\rceil\)个数,使得 ...

  8. Spring系列__01HelloWorld

    Spring作为一款成熟的Java框架,其优点和意义不用我多说,可以参考:https://m.w3cschool.cn/wkspring/pesy1icl.html 今天开始写一下Spring家族的总 ...

  9. IntelliJ IDEA最新破解版2018.3.1(附2018.2.2 完美破解教程)

    2018.3.1最新版破解 1.官网下载IDEA 2018.3.1的商业版本点我去下载 2.破解jar下载:JetbrainsIdesCrack-3.4-release-enc.jar点我去下载 3. ...

  10. VB控件间的拖放

    新建工程,放置控件Picture1,Text1,Text2,复制下面的代码运行 Text1和Text2可以互相拖放,也可以将Picture1拖放给Text1,Text2. Private Sub Fo ...