[原创].NET 业务框架开发实战之六 DAL的重构
.NET 业务框架开发实战之六 DAL的重构
前言:其实这个系列还是之前的".NET 分布式架构开发实战 ",之所以改了名字,主要是因为文章的标题带来了不少的歧义:系列文章中本打算开发一个简化业务发的流程的Framework,然后用这个Framework再来实战,开发一个分布式的应用。改了名字。给大家带来了不便,敬请见谅。
本篇的议题如下:
1. 确定DAL的接口的定义。
系列文章链接:
[原创].NET 分布式架构开发实战之三 数据访问深入一点的思考
[原创].NET 分布式架构开发实战之四 构建从理想和实现之间的桥梁(前篇)
[原创].NET 分布式架构开发实战五 Framework改进篇
[原创].NET 业务框架开发实战之八 业务层Mapping的选择策略
[原创].NET 业务框架开发实战之九 Mapping属性原理和验证规则的实现策略
之前在开发DAL中,提出了一些思想,也设计了一些接口。现在就把DAL的一些设计完善起来。说是“完善”,并不是说把所有的代码都实现,而是把该定义的接口,方法敲定下来。Richard认为,设计一个架构或者Framework的时候,开始是接口的定义,定义好各层之间交互的接口,然后才是具体代码的实现。
因为在设计Framework的时候,首先要考虑这个Framework的使用者是谁,希望他们怎么样来使用开发出来的这个Framework。在这里,Richard很明白:Framework的使用者就是自己公司里的开发人员。而且还要使得开发的使用尽量的方便,不要到处去配置一些文档,最好就是把Framework引入进来,稍微配一下就使用。
在Richard设计的Framework中,就DAL而言,如果希望DAL返回DataTable,DataReader等给BLL,那么需要配置的仅仅只是指明数据库的连接字符串;如果希望DAL返回的数据实体给BLL,那么就得把一张张的表映射成为实体,然后让这些实体继承IDataEntity接口就行了(生成实体可以用ORM工具,或者自己手写代码)。
Richard思考了之前对DAL的设计,在此他做了一些改进。
首先就是对于IDataContext的重新设计和理解:之前的设计是定义了IDataContext,然后用不同的方式实现这个接口,如LinqDataContext.Provider就是用Linq的方法来返回结果(DataResult)。现在Richard认为IDataContext其实就是用来操作数据库的,所以返回的结果就应该是操作数据之后的结果,如Update操作就返回受影响的行数或者是否更新成功。至于是否要把一些额外的信息包装返回给BLL,就不是IDataContext的实现者的事情了。而且Richard还考虑到了需要在一定程度上支持原生的ADO.NET,起码给ADO.NET预留接口。
基于此,Richard就把IDataContext定义为一个接口声明,然后再定义了IDataEntityContext,和IDataTableContext来继承IDataContext,他们的关系图如下:
其中IDataEntityContext使用Linq和Entity Framework来实现,而IDataTableContext就是用ADO.NET的方式来实现。
IDataEntityContext接口的和系列文章中定义的一些方法差不多,但是做了修改。其中有一点要提的就是:ICriteria就是所有条件对象要实现的接口(查询对象也是条件对象的一种)。例如,可以根据相应的条件删除,更新数据。
/// 所有的数据实体执行者实现这个借口
/// </summary>
public interface IDataEntityContext:IDataContext
{
TEntity Add<TEntity>(TEntity entity) where TEntity : IDataEntity;
List<TEntity> Add<TEntity>(List<TEntity> entityList) where TEntity : IDataEntity;
bool Update<TEntity>(TEntity entity) where TEntity : IDataEntity;
bool Update<TEntity>(List<TEntity> entityList) where TEntity : IDataEntity;
bool Update(ICriteria condiftion, object value);
bool Delete<TEntity>(TEntity entity) where TEntity : IDataEntity;
bool Delete<TEntity>(List<TEntity> entityList) where TEntity : IDataEntity;
bool Delete(ICriteria condition);
int GetCount(ICriteria condition);
List<TEntity> Query<TEntity>(ICriteria condition);
List<TEntity> Query<TEntity>(ICriteria condition, int pageIndex, int pageSize, ref int entityCount) where TEntity : IDataEntity;
List<object> Query(ICriteria condiftion);
}
另外就是多了一个 List<object> Query(ICriteria condiftion);方法,之所以有这个方法,Richard考虑到,可能开发人员想要直接自己写SQL语句去执行,如select avg(Count),sum(Name) from Customer...,开发人员可以写任意的语句,所以返回一个实体类不现实,就返回一个List<object>。
还有一点就是关于查询对象的改进:以前仅仅只是定义了查询对象的接口,现在用ICriteria 接口中定义来条件对象,而且还可以在条件对象声明是在对数据操作是否采用事务或者缓存。
/// 所有的条件对象都要从这个接口继承
/// </summary>
public interface ICriteria
{
string Name { get; set; }
bool IsCache { get; set; }
bool IsTransaction { get; set; }
}
之后Richard又定义了一个IDataProvider,接口,声明如下 :
/// 数据提供者要实现的借口
/// </summary>
public interface IDataProvider
{
DataResult<TEntity> Add<TEntity>(TEntity entity) where TEntity : IDataEntity;
DataResult<TEntity> Add<TEntity>(List<TEntity> entityList) where TEntity : IDataEntity;
DataResult<TEntity> Update<TEntity>(TEntity entity) where TEntity : IDataEntity;
DataResult<TEntity> Update<TEntity>(List<TEntity> entityList) where TEntity : IDataEntity;
bool Update(ICriteria condiftion, object value);
DataResult<TEntity> Delete<TEntity>(TEntity entity) where TEntity : IDataEntity;
DataResult<TEntity> Delete<TEntity>(List<TEntity> entityList) where TEntity : IDataEntity;
bool Delete(ICriteria condiftion);
int GetCount(ICriteria condition);
DataResult<TEntity> GetOne<TEntity>(ICriteria condition) where TEntity : IDataEntity;
DataResult<TEntity> GetList<TEntity>(ICriteria condition) where TEntity : IDataEntity;
DataResult<TEntity> GetPageData<TEntity>(ICriteria condition, int pageIndex, int pageSize, ref int entityCount) where TEntity : IDataEntity;
List<object> GetCustomData(ICriteria condiftion);
}
之所以要定义这个接口,其实 Richard就是想让实现了IDataContext的类踏踏实实的去做底层的数据操作,至于数据操作之后的结果以什么形式给BLL,不用IDataContext的实现者来关心,而是用IDataProvider的实现者来关心。
在IDataProvider的实现者在底层就是调用了IDataContext的实现者的方法,然后在IDataProvider中,对外提供了一些更加友好和方便使用的方法,最后在BLL中直接依赖的就是IDataProvider,而不是IDataContext。
另外,对于IDataProvider返回的DataResult也做了一些修改:如果返回的是数据实体,即 使用的是IDataEntityContext来提供底层的数据操作,那么DataResult<TEntity>是没有问题的;但是如果使用的是IDataTableContext,那么返回DataResult<TEntity>就不行了,因为IDataTableContext查询方法可能返回的DataTable,或者DataReader.所以,在设计中叶预留了一个接口:让IDataProvider返回的结果实现IDataResult接口,那么ataResult<TEntity>继承这个接口,主要用来返回数据实体,如下:
DAL的设计就到这里,下一篇文章就开始讲述对业务层的一些思考。
版权为小洋和博客园所有,转载请标明出处给作者。
http://www.cnblogs.com/yanyangtian
[原创].NET 业务框架开发实战之六 DAL的重构的更多相关文章
- [原创].NET 业务框架开发实战之十 第一阶段总结,深入浅出,水到渠成(后篇)
原文:[原创].NET 业务框架开发实战之十 第一阶段总结,深入浅出,水到渠成(后篇) .NET 业务框架开发实战之十 第一阶段总结,深入浅出,水到渠成(后篇) 前言:接着上篇来. 系列文章链接: [ ...
- [原创].NET 业务框架开发实战之九 Mapping属性原理和验证规则的实现策略
原文:[原创].NET 业务框架开发实战之九 Mapping属性原理和验证规则的实现策略 .NET 业务框架开发实战之九 Mapping属性原理和验证规则的实现策略 前言:之前的讨论一直关注在怎么从D ...
- [原创].NET 业务框架开发实战之八 业务层Mapping的选择策略
原文:[原创].NET 业务框架开发实战之八 业务层Mapping的选择策略 .NET 业务框架开发实战之八 业务层Mapping的选择策略 前言:在上一篇文章中提到了mapping,感觉很像在重新实 ...
- [原创].NET 业务框架开发实战之七 业务层初步构想
原文:[原创].NET 业务框架开发实战之七 业务层初步构想 .NET 业务框架开发实战之七 业务层初步构想 前言:本篇主要讲述如何把DAL和BLL衔接起来. 本篇议题如下: 1. DAL ...
- [原创].NET 分布式架构开发实战五 Framework改进篇
原文:[原创].NET 分布式架构开发实战五 Framework改进篇 .NET 分布式架构开发实战五 Framework改进篇 前言:本来打算这篇文章来写DAL的重构的,现在计划有点改变.之前的文章 ...
- [原创].NET 分布式架构开发实战之四 构建从理想和实现之间的桥梁(前篇)
原文:[原创].NET 分布式架构开发实战之四 构建从理想和实现之间的桥梁(前篇) .NET 分布式架构开发实战之四 构建从理想和实现之间的桥梁(前篇) 前言:上一篇文章讲述了一些实现DAL的理论,本 ...
- [原创].NET 分布式架构开发实战之三 数据访问深入一点的思考
原文:[原创].NET 分布式架构开发实战之三 数据访问深入一点的思考 .NET 分布式架构开发实战之三 数据访问深入一点的思考 前言:首先,感谢园子里的朋友对文章的支持,感谢大家,希望本系列的文章能 ...
- [原创].NET 分布式架构开发实战之二 草稿设计
原文:[原创].NET 分布式架构开发实战之二 草稿设计 .NET 分布式架构开发实战之二 草稿设计 前言:本篇之所以称为草稿设计,是因为设计的都是在纸上完成的.反映了一个思考的过程. 本篇的议题如下 ...
- [原创].NET 分布式架构开发实战之一 故事起源
原文:[原创].NET 分布式架构开发实战之一 故事起源 .NET 分布式架构开发实战之一 故事起源 前言:本系列文章主要讲述一个实实在在的项目开发的过程,主要包含:提出问题,解决问题,架构设计和各个 ...
随机推荐
- Android监控程序本身被卸载方法汇总
本文章由Jack_Jia编写,转载请注明出处. 文章链接: http://blog.csdn.net/jiazhijun/article/details/10157901 作者:Jack_Jia ...
- poj 2299 树状数组求逆序数+离散化
http://poj.org/problem?id=2299 最初做离散化的时候没太确定可是写完发现对的---由于后缀数组学的时候,,这样的思维习惯了吧 1.初始化as[i]=i:对as数组依照num ...
- HGE基础教程
作者:寰子 来源:http://www.hgechina.com/前言: 写道: 无意中发现了hge中文社区,听朋友介绍,认识了hge,然后开始对它进行研究,并使用hge开始制作游戏. 因为我所得的资 ...
- Learning Cocos2d-x for WP8(1)——创建首个项目
原文:Learning Cocos2d-x for WP8(1)--创建首个项目 Cocos2d-x for WP8开发语言是C++,系列文章将参考兄弟篇Learning Cocos2d-x for ...
- HashMap源码解读(转)
http://www.360doc.com/content/10/1214/22/573136_78188909.shtml 最近朋友推荐的一个很好的工作,又是面了2轮没通过,已经是好几次朋友内推没过 ...
- 关于oracle的备份 导入
****假设要保存为bat文件.最好用汉字 导入: imp clsoftoa/clsoftoa@orcl124 --要导入的数据库的 username/password@数据库名 fromuser= ...
- poj3176--Cow Bowling(dp:数塔问题)
Cow Bowling Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 14028 Accepted: 9302 Desc ...
- java 字符串 asc 加密解密
package com; public class MD5Test { /** * @param args */ public static void main(String[] args) { Sy ...
- WPF与混淆器
原文:WPF与混淆器 时至今日,混淆依然是.Net程序的一道重要保护手段,而混淆器对WPF应用程序的支持是怎样的呢?我们今天就通过实例讲解一下. 首先建立如下图所示的简单的用户界面: 在界面代码中设置 ...
- Android编程心得-Service数据绑定初步
在Android里,Service的数据绑定是一种重要的用法,我们知道Service与Activity一样是运行在当前应用进程的主线程里面的,他们之间交互的方式有多种,下面我来介绍一下如何使用数据绑定 ...