.NET 业务框架开发实战之九 Mapping属性原理和验证规则的实现策略

  前言:之前的讨论一直关注在怎么从DAL中获取数据,以及数据的Mapping问题。实际上,一个业务框架最主要的作用就是简化业务逻辑的编写和开发。

  本篇的议题如下:

  1. 框架的借鉴
  2. 综合考虑

  系列文章链接:

[原创].NET 分布式架构开发实战之一 故事起源

[原创].NET 分布式架构开发实战之二 草稿设计

[原创].NET 分布式架构开发实战之三 数据访问深入一点的思考

[原创].NET 分布式架构开发实战之四 构建从理想和实现之间的桥梁(前篇)

[原创].NET 分布式架构开发实战五 Framework改进篇

[原创].NET 业务框架开发实战之六 DAL的重构

[原创].NET 业务框架开发实战之七 业务层初步构想

[原创].NET 业务框架开发实战之八 业务层Mapping的选择策略

[原创].NET 业务框架开发实战之九 Mapping属性原理和验证规则的实现策略

[原创].NET 业务框架开发实战之十 第一阶段总结,深入浅出,水到渠成(前篇)

[原创].NET 业务框架开发实战之十 第一阶段总结,深入浅出,水到渠成(后篇)

  1. 框架的借鉴

  一个框架的产生不是那么简单的,有很多的问题需要Richard去考虑:

  1. 避免重新造轮子
  2. 借鉴现有的成熟的框架的思想

在开发的过程中,Richard一直使用Visual Studio IDE开发。而且每次随着VS新版本的发布,总是伴随着新技术的产生。很多的时候,开发人员只是关注在新技术的使用和学习上。但是对于新技术,还有另外一方面是很值得关注的:实现的原理,和为什么这样实现,即,思想。新技术,毫无疑问是一些大师们思考的结果,从他们的思想中借鉴,益处是很大的。

在Richard学习的过程中,有一个地方特别引起来他的关注:那就是依赖属性概念的提出,先是WPF,然后在他学习WF的时候,也看到了依赖属性的再次使用。他考虑,把依赖属性的思想使用到自己正在开发的业务框架中来。

首先,他分析了现在的依赖属性的实现方式(以WPF为例),

代码

public class FrameworkElement: UIElement, ...

{

public static readonly DependencyProperty MarginProperty;

...

}

public Thickness Margin
{

set { SetValue(MarginProperty, value); }

get { return (Thickness)GetValue(MarginProperty); }

}

static FrameworkElement()
{

FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata(

new Thickness(), FrameworkPropertyMetadataOptions.AffectsMeasure);

MarginProperty = DependencyProperty.Register("Margin",

typeof(Thickness), typeof(FrameworkElement), metadata,

new ValidateValueCallback(FrameworkElement.IsMarginValid));   ...

}

在Richard一直认为,一个属性的声明是很简单的,而且长期以来Richard都一直使用下面的方式:

public Thickness Margin
{

get;set;

}

  比较而言,依赖属性最大的好处就于:给普通的属性提供更加多的信息,而且提供了更多的功能:验证,触发回调事件。当然,使用普通的属性也能达到:

  

public Thickness Margin
{

get{return margin;}
       set
       {

if(margin<0)
                     ...
              ...
       }
}

相比而言,依赖的属性的方式更加优雅,而且扩展性也好。

还有一点比较重要的就是,一旦把一个属性变为依赖属性,那么.NET Framework就开始管理这个属性,如自动的验证,值的改变和跟踪。这样就把任务交给了Framework,开发人员做事情就比较方便了。

Richard想起了之前在开发业务类中遇到的问题:例如下面的代码:

public class Product
{

public string ProductName{get;set;}

public double Price{get;set;}

}

很多的时候,在增加或者更新一个Product的时候,由于逻辑的需要,往往要判断ProductName不为空,而且Price要大于零等。所以每次都需要写代码判断:

        public void Add()
        {

if(string.IsNullOrEmpty(this.ProductName){...}

if(this.Price<0){...}

}

  问题还不止这些,如果在其他的业务类中也需要同样,而且类似的验证,那只有一行行的写类似的代码,最好的情况就是copy一些代码。

这样写代码确实很累,后面Richard也想用一些方式来改进,用到了Enterprise Library中的Validation验证模块,于是代码就变成了下面的样子:

public class Product
{

[NotNullValidator]

public string ProductName{get;set;}

public double Price{get;set;}

}

使用声明的开发,AOP的思想,其实这样的方式相比之前而言,确实已经很不错了。在把业务类的数据保存的时候只要调用Validation验证模块的Validate()方法就行了。确实很方便,但是存在的问题就是:每次调用Validate()方法时候,就会把这个业务类的所有属性都会检查一遍(那些加了验证标签的属性),这样,性能方面不好,而且还不能针对某一个属性单独的验证。

  2. 综合考虑

Richard还考虑到了另外的一点:之前一直在解决mapping的问题,说到底就是把从DAL中拿到的数据赋值给业务类的属性。而且还要基于业务类创建查询对象,最后把查询对象解析为SQL语句,所以还要保存业务属性和DAL中数据实体属性的对应关系,即哪个业务属性对应哪个数据实体属性(也是表字段)。

综合上面的考虑,Richard决定把依赖属性的优势利用起来(自动的验证,数据改变跟踪,另外加上权限的验证),而且给依赖属性更多的元数据信息:把mapping的字段信息保存在依赖属性中。所以,现在属性的声明如下:

代码

public static readonly PropertyInfo<int> ProductIdProperty = RegisterProperty<Product>(
            new PropertyInfo<int>("ProductId",typeof(M_Product)","Id"));

public string ProductId
    {

get { return ReadProperty(ProductIdProperty); }
      set { LoadProperty(ProductIdProperty, value); }
    }

在上面的属性声明中,就指定从业务类(如,Product)的属性从哪个数据实体(typeof(m_Product))的哪个属性(如,Id)取值。

RegisterProperty就是把属性的信息保存在一个字典中:

Dictionary<Type,List< IPropertyInfo>>

其中PropertyInfo继承了IPropertyInfo接口。

最后的结果就是:所有业务类的mapping属性都被保存在了一个全局的静态字典中。

 

另外还有一个全局的静态字典用来保存每个属性所对应的验证规则:

Dictionary< IPropertyInfo,List<ICheckRule>>

所有的验证规则都是从ICheckRule接口继承。

一个比较强大的属性就产生了。当然,在mapping属性中的验证只是基本的验证,还有更加复杂的业务验证将会放在其他的地方,实现方式或者类似WPF那么:采用回调,如new ValidateValueCallback(FrameworkElement.IsMarginValid)。

所以,借鉴于mapping属性就解决了三个问题:

  1. mapping和查询对象的实现
  2. 部分验证规则的声明
  3. 业务属性的管理

   版权为小洋和博客园所有,欢迎转载,转载请标明出处给作者。

     http://www.cnblogs.com/yanyangtian

  下篇讲述:.NET 业务框架开发实战之十 水到渠成,发布框架实现的第一个版本

转载于:https://www.cnblogs.com/yanyangtian/archive/2010/06/17/1759327.html

[原创].NET 业务框架开发实战之九 Mapping属性原理和验证规则的实现策略相关推荐

  1. [原创].NET 业务框架开发实战之十 第一阶段总结,深入浅出,水到渠成(前篇)...

    .NET 业务框架开发实战之十 第一阶段总结,深入浅出,水到渠成(前篇) 前言:这个系列有段时间没有动了.主要是针对大家的反馈在修改代码.在修改的过程中,也有了一些新的体会,这里和大家分享一下,同时也 ...

  2. [原创].NET 业务框架开发实战之六 DAL的重构

    .NET 业务框架开发实战之六 DAL的重构 前言:其实这个系列还是之前的".NET 分布式架构开发实战 ",之所以改了名字,主要是因为文章的标题带来了不少的歧义:系列文章中本打算 ...

  3. [原创].NET 业务框架开发实战之十 第一阶段总结,深入浅出,水到渠成(后篇)...

    .NET 业务框架开发实战之十 第一阶段总结,深入浅出,水到渠成(后篇) 前言:接着上篇来. 系列文章链接: [原创].NET 分布式架构开发实战之一 故事起源 [原创].NET 分布式架构开发实战之 ...

  4. [原创].NET 分布式架构开发实战五 Framework改进篇

    原文:[原创].NET 分布式架构开发实战五 Framework改进篇 .NET 分布式架构开发实战五 Framework改进篇 前言:本来打算这篇文章来写DAL的重构的,现在计划有点改变.之前的文章 ...

  5. [原创].NET 分布式架构开发实战之一 故事起源

    阅读: 1320 评论: 18 作者: 小洋(燕洋天工作室) 发表于 2010-05-23 09:03 原文链接 .NET 分布式架构开发实战之一 故事起源 前言:本系列文章主要讲述一个实实在在的项目 ...

  6. 企业级业务系统开发实战-序言

    前些年一直在做微软的解决方案实施与软件开发的工作.在学习.项目实施.开发与管理的过程中学到了别人不少好的东西,也自身总结了大量的经验,希望能够通过一个系列来跟大家分享关于软件开发方面的内容. 这个开发 ...

  7. iOS开发实战之手机号、座机号正则验证

    早些时候一直在写微信小程序..NETWeb Api相关的教程,写教程就像人生一样,走走停停,思前想后,有什么得失,有什么可以总结与提高. 昨天晚些时候基本上被马保国对阵拳击的视频给刷屏了,顺便在这里发 ...

  8. php实战开发管理系统,深入浅出PHP框架Thinkphp实战开发(权限管理、CMS内容管理系统)...

    Thinkphp课程大纲: ThinkPHP 是一个免费开源的,快速.简单的面向对象的 轻量级PHP开发框架 ,创立于2006年初,遵循Apache2开源协议公布,是为了敏捷WEB应用开发跟简化企业应 ...

  9. python接口自动化测试书籍_蜗牛出版之《接口自动化测试开发实战教程》书籍详解!...

    各位老铁,大家好~ 上周,我们通过一篇分享,给大家详细介绍了蜗牛创想的出版业务. 还不了解的小伙伴请戳:除了培训和研发,我们还有一项90%的人都未曾关注到的业务! 本周开始,我们将对已经出版的< ...

最新文章

  1. 程序员硬核资源:一本贼有趣的设计模式学习pdf
  2. crontab 命令
  3. UVA 617 - Nonstop Travel(数论+暴力枚举)
  4. web实现远程桌面:Apache Guacamole
  5. 漫步最优化三十五——共轭
  6. m3u8和HLS下载和分析工具
  7. 使用青云主机的GPU主机教程(不完整版)
  8. NO32 网络层次及OSI7层模型--TCP三次握手四次断开--子网划分
  9. 独家揭秘阿里云SQL Server AlwaysOn集群版重大突破
  10. [导入]设置wap服务器
  11. Android的常用零碎代码块
  12. Atitit 提升稳定性 数据库死锁 目录 1.1. 配置数据库死锁检测超时时间从默认50s到10s 1 1.2. 调整隔离级别到read commit 1 1.3. mysql数据库连接使用完毕
  13. linux视频补帧,SVP(电脑视频补帧软件) V4.3.180 Linux版
  14. Unity打开外部文件夹并选择文件
  15. Java计算圆、长方形、正方形的面积及周长,并比较打印各个图形的大小
  16. Integer类型的比较
  17. Python界面编程第二课:Pyside2 创建窗口 (Python GUI)
  18. 毛球科技|区块链如何改变商业生活
  19. mongodb的write concern
  20. 图像采集数据集整理和扩充方案(含代码)

热门文章

  1. 记录某一天安服仔的漏洞挖掘过程
  2. acrgis api for javaScript需要对Dojo了解多少?
  3. 分布式系统理论之租约机制学习
  4. hive性能优化指南
  5. 机器学习实战:使用lightGBM预测饭店流量
  6. TransmittableThreadLocal 解决 线程池线程复用 无法复制 InheritableThreadLocal 的问题.
  7. 行为型模式:状态模式
  8. php-redis 下载地址
  9. Python操作Redis的5种数据类型
  10. Java——递归调用