仓储的实现深入篇

上传人:206****923 文档编号:90703569 上传时间:2019-06-15 格式:DOC 页数:21 大小:50.50KB
返回 下载 相关 举报
仓储的实现深入篇_第1页
第1页 / 共21页
仓储的实现深入篇_第2页
第2页 / 共21页
仓储的实现深入篇_第3页
第3页 / 共21页
仓储的实现深入篇_第4页
第4页 / 共21页
仓储的实现深入篇_第5页
第5页 / 共21页
点击查看更多>>
资源描述

《仓储的实现深入篇》由会员分享,可在线阅读,更多相关《仓储的实现深入篇(21页珍藏版)》请在金锄头文库上搜索。

1、仓储的实现:深入篇 早在年前的时候就已经在CSAI博客发表了上一篇文章:仓储的实现:基础篇。苦于日夜奔波于工作与生活之间,一直没有能够抽空继续探讨仓储的实现细节,也让很多关注EntityFramework和领域驱动设计的朋友们备感失望。闲话不多说,现在继续考虑,如何让仓储的操作在相同的事物处理上下文中进行。DDD引入仓储模式,其目的之一就是能够通过仓储隐藏对象持久化的技术细节,使得领域模型变得更为“纯净”。由此可见,仓储的实现是需要基础结构层的组件支持的,表现为对数据库的操作。在传统的关系型数据库操作中,事务处理是一个很重要的概念,虽然从目前某些大型项目看,事务处理会降低效率,但它保证了数据的

2、完整性。关系型数据库仍然是目前数据持久化机制的主流,事务处理的实现还是很有必要的。为了迎合仓储模式,就需要对经典的ObjectContext使用方式作一些调整。比如,原本我们可以非常简单地使用using (EntitiesContainer ec = new EntitiesContainer()语句来界定LINQ to Entities的操作范围,并使用ObjectContext的SaveChanges成员方法提交事务,而在引入了仓储的实现中,就不能继续采用这种经典的使用方式。这让EntityFramework看上去变得很奇怪,也很牵强,我相信很多网友会批评我的做法,因为我把问题复杂化了。其

3、实,这应该是关注点不同罢了。关注EntityFramework的开发人员,自然觉得经典的调用方式简单明了,而从DDD的角度看呢?只能把关注点放在仓储上,而把EntityFramework当成是仓储的一种技术选型(当然从DDD角度讲,我们完全可以不选择EntityFramework,而去选择其它技术)。所以本文暂且抛开EntityFramework,继续在上文的基础上,讨论仓储的实现。前面提到,仓储的实现需要考虑事务处理,而且根据DDD的经验,针对每一个聚合根,都需要有个仓储对其进行持久化以及对象重新组装等操作。为此,我的想法是,将仓储操作“界定”在某一个事务处理上下文(Context)中,仓储

4、的实例是由Context获得的,这有点像EntityFramework中ObjectContext与EntityObject的关系那样。由于仓储是来自于transaction context,所以它知道目前处于哪个事务上下文中。我定义的这个transaction context如下:隐藏行号 复制代码 ?Transaction Contextpublic interface IRepositoryTransactionContext : IDisposable IRepository<TEntity> GetRepository<TEntity>() where TEn

5、tity : EntityObject, IAggregateRoot; void BeginTransaction(); void Commit(); void Rollback();上面第三行代码定义了一个接口方法,这个方法的主要作用就是返回一个针对指定聚合根实体的仓储实例。剩下那三行代码就很明显了,那是标准的transaction操作:启动事务、提交事务以及回滚事务。在设计上,可以根据需要,选择合适的技术来实现IRepositoryTransactionContext。我们现在讨论的是EntityFramework,所以我将给出EntityFramework的具体实现。当然,如果你不选用

6、EntityFramework,而是用NHibernate实现数据持久化,这样的设计同样能够使你达到目的。以下是基于EntityFramework的实现:EdmRepositoryTransactionContext的伪代码。隐藏行号 复制代码 ?EdmRepositoryTransactionContextinternal class EdmRepositoryTransactionContext : IRepositoryTransactionContext private ObjectContext objContext; private Dictionary<Type, obje

7、ct> repositoryCache = new Dictionary<Type, object>(); public EdmRepositoryTransactionContext(ObjectContext objContext) this.objContext = objContext; #region IRepositoryTransactionContext Members public IRepository<TEntity> GetRepository<TEntity>() where TEntity : EntityObject, I

8、AggregateRoot if (repositoryCache.ContainsKey(typeof(TEntity) return (IRepository<TEntity>)repositoryCachetypeof(TEntity); IRepository<TEntity> repository = new EdmRepository<TEntity>(this.objContext); this.repositoryCache.Add(typeof(TEntity), repository); return repository; public

9、 void BeginTransaction() / We do not need to begin a transaction here because the object context, / which would handle the transaction, was created and injected into the / constructor by Castle Windsor framework. public void Commit() this.objContext.SaveChanges(); public void Rollback() / We also do

10、 not need to perform the rollback operation because / entity framework will handle this for us, just when the execution / point is stepping out of the using scope. #endregion #region IDisposable Members public void Dispose() this.repositoryCache.Clear(); this.objContext.Dispose(); #endregionEdmRepos

11、itoryTransactionContext被定义为internal,这个设计是合理的,因为Domain层是不需要知道事务上下文的具体实现,它将会被IoC/DI容器注入到Domain层中(本系列文章采用Castle Windsor框架)。在EdmRepositoryTransactionContext的构造函数中,它需要EntityFramework的ObjectContext对象来初始化实例。同样,由于IoC/DI的使用,我们在代码中也是不需要去创建这个ObjectContext的,交给Castle Windsor就OK了。第13行的GetRepository方法简单地采用了Diction

12、ary对象来实现缓存仓储实例的效果,当然这种做法还有待改进。EdmRepositoryTransactionContext是不需要BeginTransaction的,我们将方法置空,因为EntityFramework的事务会由ObjectContext来管理,同理,Rollback也被置空。EdmRepository的实现就比较显而易见了,请参见上文。此外,我们还可以针对NHibernate实现仓储模式,只需要实现IRepositoryTransactionContext和IRepository接口即可,比如:隐藏行号 复制代码 ?NHibernateRepositoryTransaction

13、Context实现internal class NHibernateRepositoryTransactionContext : IRepositoryTransactionContext ITransaction transaction; Dictionary<Type, object> repositoryCache = new Dictionary<Type, object>(); public ISession Session get return DatabaseSessionFactory.Instance.Session; #region IReposit

14、oryTransactionContext Members public IRepository<TEntity> GetRepository<TEntity>() where TEntity : EntityObject, IAggregateRoot if (repositoryCache.ContainsKey(typeof(TEntity) return (IRepository<TEntity>)repositoryCachetypeof(TEntity); IRepository<TEntity> repository = new NHibernateRepository<TEntity>(this.Session); this.repositoryCache.Add(typeof(TEntity), repository); return repository; public void BeginTransaction() transaction = DatabaseSessionFactory.Instance.Session.BeginTransaction(); public void Commit()

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 中学教育 > 其它中学文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号