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 // ...
随机推荐
- ASP.NET Aries 开发框架(已支持.NET Core)
背景: 当年,在卖弄与开源QBlog时,也曾想过把QBlog的开发理念整理整理,独立一个框架来开源. 不过,人越长大就越憔悴,激情终敌不过疲惫的惰性,最终无痕而终,连3.0的版本也没开源出来. 关于框 ...
- acl权限命令
1.查看acl命令 getfacl 文件名 #查看acl权限 2.设定acl权限命令 setfacl 选项 文件名 选项: -m 设置ACL权限 -x 删除指定的ACL权限 -b 删除所有的ACL设定 ...
- md5 加密文件
import hashlibimport os def get_md5(file_path): md5 = None if os.path.isfile(file_path): f = open(fi ...
- h5适配的解决方案
一. 流程 设计师以750pt×1334pt尺寸进行设计(当然高度随内容变化),最后用该尺寸的设计稿进行标注.切图,前端采用淘宝的开源方案flexible进行适配. 二. flexible使用方法 F ...
- 【常用指令】git+服务器+数据库
git日程操作 服务器常用操作 ①同步master git pull origin master ②创建分支 git checkout -b 分支名 ③常规操作 git diff git add 文件 ...
- Android简单计时器
本文利用ContextMenu(上下文菜单),Chronometer实现简单计数器. Main.xml: <?xml version="1.0" encoding=" ...
- android 2018 面试题
四大组件:activity.service.content provider.broadcast receiver [一]Activity 1.生命周期 onCreate:表示activity正在被创 ...
- 长沙学院APP之校园模块设计
一.简单回顾 在上次的scrum冲刺中,我将整个长沙学院的APP做了一个基本的架构设计以及框架设计,确定好了APP的功能结构以及实现时所要达到的效果,并且做了一个简单的用户登录界面,由于所学知识有限, ...
- 1.1 What is the plug-in?
A game center, such as Lianzhong in China, supports hundreds of games such as Chess, Bridges, ...
- Cookie丢失的原因
最近在运行项目遇见cookie丢失的问题,这里简单总结了几点 1.Cookie的Domain设置不正确2.Cookie超时3.Cookie中含有一些非法字符,致使浏览器丢弃Cookie4.程序源码可能 ...