Unit Of Work--工作单元(二)
回顾
上一篇我们根据工作单元的原理基于ADO.NET进行了简单的实现,但是当项目需求发生变化的时候,比如需要引入ORM框架又要兼容当前ADO.NET实现的方式时,先前的实现就无法满足这个需求了。
话就不多说了,我们就跟据当前的需求变化来重构工作单元吧。
重构UnitOfWork
首先我们看看原先实现的工作单元提取出来的接口,代码如下:
public interface IUnitOfWork
{
void RegisterAdd(string sql, params IDataParameter[] parameters);
void RegisterSave(string sql, params IDataParameter[] parameters);
void RegisterRemove(string sql, params IDataParameter[] parameters);
void Comit();
}
由于需求需要兼容ORM和ADO.NET方式,而以上的接口仅仅支持ADO.NET的方式,因此接口需要改变,例如:
//其他代码省略
void RegisterAdd(object entity);
观察以上的修改会发现如果要满足需求,则需要判断是ADO.NET或者是ORM的操作,那么就有了两种不同的职责,这显然是不合理的,但是如果我们将ADO.NET和ORM还是让对应的数据层类去实现的话,就符合单一责任了,于是经过以上分析,就可以对以上的接口做进一步的修改了,大致代码如下:
//其他代码省略
void RegisterAdd(object entity, IUnitOfWorkRepository repository);
按照这个思路的话,这个IUnitOfWorkRepository的方法数量则会跟IUnitOfWork基本相同(没有Commit),一个是注册,而另一个则是实际的操作,因此接口代码则会跟第一次改为object的相同了,代码如下:
public interface IUnitOfWorkRepository
{
void ExecuteAdd(object entity);
void ExecuteSave(object entity);
void ExecuteRemove(object entity);
}
有了以上的改变之后,就可以实现IUnitOfWork了,代码结构上还是跟SQLUnitOfWork类似的,差别是原先是使用一个List<SQLEntity>来存储所有的CUD操作,但是现在必须要区分出不同类型的操作,因此需要有分别存储CUD的容器,大致代码如下:
public class UnitOfWork : IUnitOfWork
{
private Dictionary<object, IUnitOfWorkRepository> m_addList =
new Dictionary<object, IUnitOfWorkRepository>();
private Dictionary<object, IUnitOfWorkRepository> m_saveList =
new Dictionary<object, IUnitOfWorkRepository>();
private Dictionary<object, IUnitOfWorkRepository> m_removeList =
new Dictionary<object, IUnitOfWorkRepository>(); public void RegisterAdd(object entity, IUnitOfWorkRepository repository)
{
if (!this.m_addList.ContainsKey(entity))
this.m_addList.Add(entity, repository);
} public void RegisterSave(object entity, IUnitOfWorkRepository repository)
{
if (!this.m_saveList.ContainsKey(entity))
this.m_saveList.Add(entity, repository);
} public void RegisterRemove(object entity, IUnitOfWorkRepository repository)
{
if (!this.m_removeList.ContainsKey(entity))
this.m_removeList.Add(entity, repository);
} public void Commit()
{
using (TransactionScope trans = new TransactionScope())
{
foreach (var entity in this.m_addList.Keys)
{
this.m_addList[entity].ExecuteAdd(entity);
} foreach (var entity in this.m_saveList.Keys)
{
this.m_saveList[entity].ExecuteSave(entity);
} foreach (var entity in this.m_removeList.Keys)
{
this.m_removeList[entity].ExecuteRemove(entity);
}
trans.Complete();
}
}
}
到这里我们就将工作单元重构工作完成了,接下来就可以根据IUnitOfWorkRepository派生出基于ADO.NET和ORM的实现了。
重构SchoolRepository
首先我们先看一下重构后的代码:
class SchoolRepository : IRepository, IUnitOfWorkRepository
{
private IDbConnection m_connection = null;
private IUnitOfWork m_uow = null; public SchoolRepository(IDbConnection connection, IUnitOfWork uow)
{
this.m_connection = connection;
this.m_uow = uow;
} public void Add(object entity)
{
this.m_uow.RegisterAdd(entity, this);
} public void Save(object entity)
{
this.m_uow.RegisterSave(entity, this);
} public void Remove(object entity)
{
this.m_uow.RegisterRemove(entity, this);
} public void ExecuteAdd(object entity)
{
School school = entity as School;
using (IDbCommand cmd = this.m_connection.CreateCommand())
{
cmd.CommandType = CommandType.Text;
cmd.CommandText = "insert school values(@id, @name)";
cmd.Parameters.Add(new SqlParameter("@id", school.Id));
cmd.Parameters.Add(new SqlParameter("@name", school.Name));
cmd.ExecuteNonQuery();
}
} public void ExecuteSave(object entity)
{
//代码略
} public void ExecuteRemove(object entity)
{
//代码略
}
}
IRepository是数据层的基础接口,从代码中我们看到原先CUD的方法被拆分到了CUD和ExecuteXXX方法中去了,CUD方法负责调用IUnitOfWork的接口,而ExecuteXXX则实现具体的数据库操作
基于NHibernate的IUnitOfWorkRepository实现
先看代码吧
class SchoolRepository : IRepository, IUnitOfWorkRepository
{
private IUnitOfWork m_uow = null; public SchoolRepository(IDbConnection connection, IUnitOfWork uow)
{
this.m_uow = uow;
} public void Add(object entity)
{
this.m_uow.RegisterAdd(entity, this);
} public void Save(object entity)
{
this.m_uow.RegisterSave(entity, this);
} public void Remove(object entity)
{
this.m_uow.RegisterRemove(entity, this);
} public void ExecuteAdd(object entity)
{
SessionFactory.CurrentSession.Add(entity);
} public void ExecuteSave(object entity)
{
//代码略
} public void ExecuteRemove(object entity)
{
//代码略
}
}
从基于NHibernate的实现中,我们可以看到ExecuteXXX的方法都是去调用NHibernateSession的相关方法的。
结尾
到此数据层就只差查询了,下次会分享一下关于查询的模式。
文章到这里就结束了,如果有什么问题和错误欢迎留言,谢谢!
Unit Of Work--工作单元(二)的更多相关文章
- ABP(现代ASP.NET样板开发框架)系列之12、ABP领域层——工作单元(Unit Of work)
点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之12.ABP领域层——工作单元(Unit Of work) ABP是“ASP.NET Boilerplate Pr ...
- ABP领域层——工作单元(Unit Of work)
ABP领域层——工作单元(Unit Of work) 点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之12.ABP领域层——工作单元(Unit Of work) ...
- 解析ABP框架中的事务处理和工作单元,ABP事务处理
通用连接和事务管理方法连接和事务管理是使用数据库的应用程序最重要的概念之一.当你开启一个数据库连接,什么时候开始事务,如何释放连接...诸如此类的. 正如大家都知道的,.Net使用连接池(connec ...
- [Abp 源码分析]六、工作单元的实现
0.简介 在 Abp 框架内部实现了工作单元,在这里讲解一下,什么是工作单元? Unit Of Work(工作单元)模式用来维护一个由已经被业务事物修改(增加.删除或更新)的业务对象组成的列表.Uni ...
- 【.Net设计模式系列】工作单元(Unit Of Work)模式 ( 二 )
回顾 在上一篇博客[.Net设计模式系列]仓储(Repository)模式 ( 一 ) 中,通过各位兄台的评论中,可以看出在设计上还有很多的问题,在这里特别感谢 @横竖都溢 @ 浮云飞梦 2位兄台对博 ...
- [.NET领域驱动设计实战系列]专题四:前期准备之工作单元模式(Unit Of Work)
一.前言 在前一专题中介绍了规约模式的实现,然后在仓储实现中,经常会涉及工作单元模式的实现.然而,在我的网上书店案例中也将引入工作单元模式,所以本专题将详细介绍下该模式,为后面案例的实现做一个铺垫. ...
- 换个角度说工作单元(Unit Of Work):创建、持有与API调用
看到一些工作单元的介绍,有两种感觉,第一种是很学院,说了等于没说,我估计很多都是没有自己引入到实际的项目中去,第二种是告诉我一种结果,说这就是工作单元,但是没说为什么要这么使用.所以,本篇想要探讨的是 ...
- 基于DDD的.NET开发框架 - ABP工作单元(Unit of Work)
返回ABP系列 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应 ...
- 工作单元(Unit of Work)
维护受业务事务影响的对象列表,并协调变化的写入和并发问题的解决. 从DB中存取Data时,必须记录增删改动作,以将对DB有影响的数据写会到DB中去. 如果在每次修改对象模型时就对DB进行相应的修改,会 ...
随机推荐
- Lingo 做线性规划 - Asset allocation and Portfolio models
Reference: <An Introduction to Management Science Quantitative Approaches to Decision Making, Rev ...
- lucene如何通过docId快速查找field字段以及最近距离等信息?
http://www.cnblogs.com/LBSer/p/4419052.html 1 问题描述 我们的检索排序服务往往需要结合个性化算法来进行重排序,一般来说分两步:1)进行粗排序,这一过程由检 ...
- eclipse中gradle的使用
安装gradle gradle默认的本地缓存库在c盘user目录下的.gradle文件夹下,安装好gradle后,可以添加环境变量GRADLE_USER_HOME自定义缓存位置. 安装eclipse插 ...
- 记一次https访问握手失败(handshake failure)
文章作者:luxianghao 文章来源:http://www.cnblogs.com/luxianghao/p/6239518.html 转载请注明,谢谢合作. 免责声明:文章内容仅代表个人观点, ...
- atitit.设计模式(1)--—职责链模式(chain of responsibility)最佳实践O7 日期转换
atitit.设计模式(1)---职责链模式(chain of responsibility)最佳实践O7 日期转换 1. 需求:::日期转换 1 2. 可以选择的模式: 表格模式,责任链模式 1 3 ...
- atitit.微信项目开发效率慢的一些总结
atitit.微信项目开发效率慢的一些总结 #---理念问题..这个是最大的问题.. 要有专人提升开发效率才好.. #---没有一个好的开发方法体系.... ini deve 法. fell asd+ ...
- 更新日志 - fir.im 回归,上线 Android Studio 插件
上周 fir.im 经历了一场前所未有的挑战,因为自查应用网站暂停,在事情发生4天内我们完成了自查,fir.im 正式回归.煎熬的 98 个小时,感谢开发者与用户对我们的信任和支持. 使用注意: 禁止 ...
- Liferay7 BPM门户开发之35: AssetTag的集成查询
Tag是liferay中的Asset特性,可以用来对信息进行分类,在iferay中的Asset类型为: 1. Web Content(自定义内容) 2. Documents and Media(文档库 ...
- adb uninstall
adb shell pm list packages adb uninstall com.pa.pfac
- PHP 7問世,2億網站效能翻倍有望
經過10年的漫長等待,PHP 7終於正式問世了.這個影響全球8成網站的開發語言,一舉從5.0版,跳過了功敗垂成的6.0版,一舉進入了7.0時代. 20年前初夏,1995年6月8日,一位愛解決問題的C語 ...