EF架构~FluentValidation实体检验与实体分离了
在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; }
而这种设计方式给我们以后的维护带来很多问题,具体大叔总结一下:
- 与数据实体混在一起,不利用扩展,更新实体你加的特性可能会丢失
- 如果有多个VO,那么你需要把它加到具体的VO上,因为DO的语义可能不太明确
- 不方便迁移,它与ModelState耦合太高
- 从面向对象的角度来看,它的职责太单一,引起变因太多
综上所述,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实体检验与实体分离了的更多相关文章
- EF架构~为EF DbContext生成的实体添加注释(T5模板应用)
回到目录 相关文章系列 第八回 EF架构~将数据库注释添加导入到模型实体类中 第二十一回 EF架构~为EF DbContext生成的实体添加注释(T4模板应用) 第二十二回EF架构~为EF DbCo ...
- EF架构~为EF DbContext生成的实体添加注释(T5模板应用)(转载)
转载地址:http://www.newlifex.com/showtopic-1072.aspx 最近新项目要用Entity Framework 6.x,但是我发现从数据库生成模型时没有生成字段的注释 ...
- 【转】EF架构~为EF DbContext生成的实体添加注释(T5模板应用)
嗨,没法说,EF4的TT模版加上注释后,升级到EF5的TT模版后,注释就不通用了,所以,还得再研究一下,然后把操作方法再分享出来,没辙的微软! T4模版可能有些凌乱,这在T5模版里有了不错的改进,但我 ...
- EF架构~AutoMapper对象映射工具简化了实体赋值的过程
回到目录 AutoMapper是一个.NET的对象映射工具,一般地,我们进行面向服务的开发时,都会涉及到DTO的概念,即数据传输对象,而为了减少系统的负载,一般我们不会把整个表的字段作为传输的数据,而 ...
- EF架构~通过EF6的DbCommand拦截器来实现数据库读写分离~终结~配置的优化和事务里读写的统一
回到目录 本讲是通过DbCommand拦截器来实现读写分离的最后一讲,对之前几篇文章做了一个优化,无论是程序可读性还是实用性上都有一个提升,在配置信息这块,去除了字符串方式的拼接,取而代之的是sect ...
- ASP.NET Core搭建多层网站架构【5-网站数据库实体设计及映射配置】
2020/01/29, ASP.NET Core 3.1, VS2019, EntityFrameworkCore 3.1.1, Microsoft.Extensions.Logging.Consol ...
- EF架构~基于EF数据层的实现
回到目录 之前写过关于实现一个完整的EF架构的文章,文章的阅读量也是满大的,自己很欣慰,但是,那篇文章是我2011年写的,所以,技术有些不成熟,所以今天把我的2014年写的EF底层架构公开一下,这个架 ...
- EF架构~CodeFirst数据迁移与防数据库删除
回到目录 本文介绍两个概念,防数据库自动删除,这是由于在code first模式下,当数据实体发生变化时,会对原来数据库进行删除,并将新数据表添加进来,但这对于我们的运营环境数据库,是万万不能接受的, ...
- EF架构~过滤导航属性等,拼接SQL字符串
拼接T-SQL串,并使它具有通用性 好处:与服务器建立一次连接,给服务器发一条SQL命令,即可实现 代码如下: 1 /// <summary> 2 /// 构建Insert语句串 3 // ...
随机推荐
- Y1吐槽001 怎么做产品
做一个产品,这个产品是做给用户用的还是做给领导看的完全是两个不同的出发点..做给领导看有好处,毕竟领导有知道进展的权利和指导方向的作用,还有一个好处就是表现得好. 忽略了使用者的感受是非常致命的,标模 ...
- Mysql 常见问题
------------------------------------------------ ------------------------------------------------ -- ...
- 1.SSM整合_单表的增删改查
目标:增删改查 环境:Maven+Eclipse+Tomcat7+JDK7 思维导图: 表结构 目录结构 依赖 <dependencies> <dependency> < ...
- iptables安装
1.安装iptable iptable-service #先检查是否安装了iptables service iptables status #安装iptables yum install -y ipt ...
- [Codeforces Round #516][Codeforces 1063B/1064D. Labyrinth]
题目链接:1063B - Labyrinth/1064D - Labyrinth 题目大意:给定一个\(n\times m\)的图,有若干个点不能走,上下走无限制,向左和向右走的次数分别被限制为\(x ...
- 菜鸡谈OO 第二单元总结
“欢迎来到(玄学)多线程的新世界” Homework1 单部傻瓜电梯调度 Part1 多线程设计策略 第一次学到了线程这个概念,与之前的编程体验大有不同.最大的区别在于从原本的线性发生程序变成了多个行 ...
- Vue 过滤器的使用
Vue官方文档是这样说的:Vue过滤器用于格式化一些常见的文本. 在实际项目中的使用: 定义过滤器 在src定义一个filter.js文件,里面定义过滤器函数,在最后要使用 exprot defaul ...
- Vue(MVVM)、React(MVVM)、Angular(MVC)对比
前言 昨天阿里内推电面一面,面试官了解到项目中用过Vue,就问为什么前端框架使用Vue而不适用其他的框架,当时就懵了.因为只用过Vue,不了解其他两个框架,今天就赶紧去了解一下他们之间的区别.大家发现 ...
- Pyinstaller (python打包为exe文件)
需求分析: python脚本如果在没有安装python的机器上不能运行,所以将脚本打包成exe文件,降低脚本对环境的依赖性,同时运行更加迅速. 当然打包的脚本似乎不是在所有的win平台下都能使用,wi ...
- java发送短信验证码
业务: 手机端点击发送验证码,请求发送到java服务器端,由java调用第三方平台(我们使用的是榛子云短信http://smsow.zhenzikj.com)的短信接口,生成验证码并发送. SDK下载 ...