zoukankan      html  css  js  c++  java
  • (DDD)仓储的思考

    (DDD)仓储的思考

    为什么需要仓储呢?领域对象(一般是聚合根)的被创建出来后的到最后持久化到数据库都需要跟数据库打交道,这样我们就需要一个类似数据库访问层的东西来管理领域对象。那是不是我们就可以设计一个类似DAL层的东东来管理对象呢?是的,但是呢设计上有点区别,就是我们不希望上层如应用层直接访问数据,我们所有的操作应该是围绕着领域对象来的,所以我们还设计了仓储接口在领域层,然后把仓储的实现放在基础设施层。这样的设计模式很常见,一般用来解耦的。但是仓储不处理事务,事务处理我们一般交给UnitOfWork,有关于UnitOfWork的介绍大家可以参考下我之前一篇文章UnitOfWork以及其在ABP中的应用

    ABP中设计仓储的思路,其实也很简单,就是提供领域对象的一些常用的数据库操作,一般的仓储存放的对象是聚合根,但是呢ABP没有严格区分聚合根,它简单的把所有的对象都当作聚合根,这样的设计也见于NOP中。下面我是画了ABP仓储设计的一张类图。

    这个类图中我们可以清楚的看出几个:

    1、仓储设计的意义,有人说我用EF开发DbSet<T>其实就是一个仓储的呀,我干嘛还需要重新定义一个Repository呢?答案在上图中体现的很明显,我们可能不确定以后我们的项目时候会用到其他数据库访问框架,比如NHibernate或MongoDb。那么如果我设计了IRepository这个接口后,我如果哪天我项目需要用到MongoDB了,那么我就可以继承IRepository实现一个MongoDbRepositoryBase类。

    2、AbpRepositoryBase这个基类GetAll返回的是IQueryable<T>,但是呢IQueryable返回的是一个查询分析器,不是一个结果Model。这样我们就没办法确定这个GetAll到底是返回什么,就没有办法单元测试等。这个问题之前已经在蟋蟀博文Repository 返回 IQueryable?还是 IEnumerable?中讨论过了,有兴趣的同学可以参考下哈。一般的严格DDD是不能这个直接返回IQueryable的,但是如果你不是严格的DDD就无所谓了。为此我特地参考了下netfocus的ENode的案例forum,具体可以查看博文ENode简介与各种资源汇总(持续更新中。。。)下面我们来看下netfocus专家是怎么设计的吧。因为对forum还不是很熟悉,我只找到到账号索引仓储的设计。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    namespace Forum.Domain.Accounts
    {
        /// <summary>
        /// 账号索引信息的仓储接口,用于存储账号的唯一索引信息,实现账号名称的唯一性约束
        /// </summary>
        public interface IAccountIndexRepository
        {
            /// <summary>根据账号名称检索账号索引信息
            /// </summary>
            /// <param name="accountName"></param>
            /// <returns></returns>
            AccountIndex FindByAccountName(string accountName);
            /// <summary>添加一个账号索引
            /// </summary>
            /// <param name="index"></param>
            void Add(AccountIndex index);
        }
    }

    接下来是基础设施层的实现方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    namespace Forum.Domain.Dapper
    {
        [Component]
        public class AccountIndexRepository : IAccountIndexRepository
        {
            public AccountIndex FindByAccountName(string accountName)
            {
                using (var connection = GetConnection())
                {
                    connection.Open();
                    var data = connection.QueryList(new { AccountName = accountName }, Constants.AccountIndexTable).SingleOrDefault();
                    if (data != null)
                    {
                        return new AccountIndex(data.AccountId as string, accountName);
                    }
                    return null;
                }
            }
            public void Add(AccountIndex index)
            {
                using (var connection = GetConnection())
                {
                    connection.Open();
                    connection.Insert(new
                    {
                        AccountId = index.AccountId,
                        AccountName = index.AccountName
                    }, Constants.AccountIndexTable);
                }
            }
     
            private SqlConnection GetConnection()
            {
                return new SqlConnection(ConfigSettings.ConnectionString);
            }
        }
    }

    从上面我们可以知道,它用的数据访问技术是Dapper,不是EF,它也没有IQueryable的设计,需要什么就查找什么比如FindByAccountName,这个就是严格按照DDD模式设计的仓储。这样的设计和ABP的设计各有优点,看项目需求吧。至此我的仓储也先总结到这里了,我还是DDD的初学者,可能有些理解不到位,希望相互学习共同成长。博客园已经有很多类似的文章了,这篇主要设计到ABP相关的,作为ABP的系列的一篇。

    参考文章:

    http://www.cnblogs.com/netfocus/archive/2011/10/10/2204949.html

    http://www.cnblogs.com/xishuai/p/repository-return-iqueryable-or-ienumerable.html

    http://www.cnblogs.com/jesse2013/p/ddd-repository.html

  • 相关阅读:
    selenium的持续问题解决
    为什么使用Nginx
    [转]性能测试场景设计深度解析
    [转]CentOS7修改时区的正确姿势
    [转]利用Fiddler模拟恶劣网络环境
    [转]什么是微服务
    [转] WebSocket 教程
    [转] Python实现简单的Web服务器
    shell修改配置文件参数
    [转] linux shell 字符串操作(长度,查找,替换)详解
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/4869270.html
Copyright © 2011-2022 走看看