在DDD设计中大家都会使用Repository pattern来获取domain model所需要的数据。

1.什么事Repository?

"A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection. Client objects construct query specifications declaratively and submit them to Repository for satisfaction. Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code encapsulated by the Repository will carry out the appropriate operations behind the scenes. Conceptually, a Repository encapsulates the set of objects persisted in a data store and the operations performed over them, providing a more object-oriented view of the persistence layer. Repository also supports the objective of achieving a clean separation and one-way dependency between the domain and data mapping layers."

按照最初提出者的介绍,它是衔接数据映射层和域之间的一个纽带,作用相当于一个在内存中的域对象集合。客户端对象把查询的一些实体进行组合,并把它 们提交给Repository。对象能够从Repository中移除或者添加,就好比这些对象在一个Collection对象上就行数据操作,同时映射 层的代码会对应的从数据库中取出相应的数据。

从概念上讲,Repository是把一个数据存储区的数据给封装成对象的集合并提供了对这些集合的操作。。。。。。。

在领域驱动设计中,我们有个集合(aggregate)的概念,集合是:

"A cluster of associated objects that are treated as a unit for the purpose of data changes. External references are restricted to one member of the Aggregate, designated as the root. A set of consistency rules applies within the Aggregate's boundaries.".

通常我们是对于domain的每个集合会对应的定义一个repository。也就说,并不是每个实体都会有对应的一个repository。

Repository的接口一般情况下是作为domain model的一部分,但是严格意义上讲它不属于domain model。

当我们处理aggregates时,大部分时间我们需要3个常用的相关操作。

1.通过Id得到对应的集合·。

2.向repository添加一个集合。

3.从repository中移除一个集合。

比如我们有个Order表,

那么它的Repository接口IRepository(包含三个基本的方法)如下:

假设我们还有另外一个domain model是Product,它的类如下:

它的Repository接口IProductRepository如下:

可以看出来我们的两个接口其实有很多代码是重复的,所以可以来个基本的接口IRepository,并结合System.Collection.Generic中的Generic属性来设计IRepository的代码:

对应的IProductRepository和IOrderRepository代码也得修改:

为了能够测试我们的Repository,我们这里创建一个Repository继承IProductRepository接口:

在构造函数中我们先添加product,然后再实现接口的几个方法。下面来进行单元测试:

运行后可以通过。。。

在NHibernate中使用Repository 模式。

首先我们需要创建一个session provider,如下:

现在需要hibernate.cfg.xml和product的mapping文件:

然后就可以使用单元测试了。

但是实际项目中我们很少使用这种模式。我们来分析下:

当我们有一个私有的方法是GetSession,每次访问它都会返回一个session实体,  所以Repository中的每个操作都会使用自己的session实体,当我们的项目中不是使用分布式事务时,我们都是希望这些操作都是在一个事务。

为了解决这个问题我们就可以使用UoW模式。

DDD之:Repository仓储模式的更多相关文章

  1. 从Entity Framework的实现方式来看DDD中的repository仓储模式运用

    一:最普通的数据库操作 static void Main(string[] args) { using (SchoolDBEntities db = new SchoolDBEntities()) { ...

  2. .Net Core之仓储(Repository)模式

    我们经常在项目中使用仓储(Repository)模式,来实现解耦数据访问层与业务层.那在.net core使用EF core又是怎么做的呢? 现在我分享一下我的实现方案: 一.在领域层创建Reposi ...

  3. 仓储模式Repository的选择与设计

    首次接触仓储的概念来自Eric Evans 的经典著作<领域驱动设计-软件核心复杂性应对之道>,但书中没有具体实现.如何实现仓储模式,在我这几年的使用过程中也积累了一些具体的实施经验.根据 ...

  4. Repository 仓储,你的归宿究竟在哪?(三)-SELECT 某某某。。。

    写在前面 首先,本篇博文主要包含两个主题: 领域服务中使用仓储 SELECT 某某某(有点晕?请看下面.) 上一篇:Repository 仓储,你的归宿究竟在哪?(二)-这样的应用层代码,你能接受吗? ...

  5. Repository 仓储,你的归宿究竟在哪?(二)-这样的应用层代码,你能接受吗?

    写在前面 关于"Repository 仓储,你的归宿究竟在哪?"这个系列,本来是想写个上下篇,但是现在觉得,很有多东西需要明确,我也不知道接下来会写多少篇,所以上一篇的标题就改成了 ...

  6. Repository 仓储

    Repository 仓储 写在前面 首先,本篇博文主要包含两个主题: 领域服务中使用仓储 SELECT 某某某(有点晕?请看下面.) 上一篇:Repository 仓储,你的归宿究竟在哪?(二)-这 ...

  7. Repository 仓储,你的归宿究竟在哪?(上)

    Repository 仓储,你的归宿究竟在哪?(上) 写在前面 写这篇博文的灵感来自<如何开始DDD(完)>,很感谢young.han兄这几天的坚持,陆陆续续写了几篇有关于领域驱动设计的博 ...

  8. 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之六 || API项目整体搭建 6.1 仓储模式

    前言 1.@LearningCoding 小伙伴关于用Sqlsugar在mysql数据库上的研究成果: sqlsugarcore支持mysql等数据库,在DbContext里面只需要设置dbtype为 ...

  9. 用MVC5+EF6+WebApi 做一个考试功能(六) 仓储模式 打造EF通用仓储类

    前言 年底工作比较忙,年度总结还没写,项目要上线,回老家过年各种准备.尤其是给长辈给侄子侄女准备礼物头都大了. 原来想年前先出一版能用的,我看有点悬了,尽量先把大体功能弄出来,扔掉一些,保证能考试,然 ...

随机推荐

  1. magento模板中XML与phtml关系 [四]

    layout\catalogserch.xml 中声明的 as="topSearch" 被templ\page\html\header.phtml调用输出 echo $this-& ...

  2. redis 工具类 单个redis、JedisPool 及多个redis、shardedJedisPool与spring的集成配置

    http://www.cnblogs.com/edisonfeng/p/3571870.html http://javacrazyer.iteye.com/blog/1840161 http://ww ...

  3. ListView使用的时候遇到的一些问题

    昨天在做项目时,请求服务器的好友动态后,将好友动态和评论显示到界面上,用ListView显示,发现一进这个界面时,listView的适配器的getVIew()方法就会执行6次,后来发现原来是ListV ...

  4. android 没有main函数,怎么找到程序执行入口呢?以及activity主要生命周期的方法说明

    android应用程序,由一到多个Activity组成.每个Activity没有很紧密的联系,因为我们可以在自己的程序中调用其它Activity,特别是调用自己的代码之外生成的Activity,比如a ...

  5. Yii config 配置

    Yii2 配置文件 常用配置总结 <?php // 主配置文件 $config = array( 'modules' => array( 'gii' => array( 'class ...

  6. 性能更好的js动画实现方式---requestAnimationFrame

    用js来实现动画,我们一般是借助setTimeout或setInterval这两个函数,css3动画出来后,我们又可以使用css3来实现动画了,而且性能和流畅度也得到了很大的提升.但是css3动画还是 ...

  7. linux tomcat服务器优化配置

    在 /usr/local/tomcat/bin/catalina.sh里首行加入, 防止内存不够的问题 JAVA_OPTS="-Xms512m -Xmx1024m -Xss1024K -XX ...

  8. Nginx将通过IP访问重定向

    server { listen 80 default_server; server_name localhost; location / { rewrite ^ http://www.xxx.com/ ...

  9. 关于Stringbulider类

    在使用String类构造一个字符串时,要给它分配足够的内存来保存字符串,但StringBuilder通常分配的内存会比需要的更多.开发人员可以选择显式指定StringBuilder要分配多少内存,但如 ...

  10. fiddler2 中文乱码问题

    打开注册表编辑器,找到HKCU\Software\Microsoft\Fiddler2\,在里面添加一个字符串值,名叫HeaderEncoding,值设置为默认编码.建议设成GB18030.然后要记得 ...