1、DDD领域驱动设计实践篇之如何提取模型

2、DDD领域驱动设计之聚合、实体、值对象

3、DDD领域驱动设计之领域基础设施层

4、DDD领域驱动设计之领域服务

5、整体DEMO代码

什么是运用层,说白了就是以前三层的BLL,没有什么特别,只是调用的不是以前的DAL了,而是领域层+基础设施层,运用层接口基本是可以根据原型来做的,也就是UI需要什么数据就定义什么接口,难点就在于怎么去调用领域层了,这个如果是分开来开发的话,难度会很大,为什么是很难呢,原因就在于区分职责,需要有很详细的领域层说明以及实时的参与领域建模。

运用层代码1

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Linq.Expressions;
  5. using DDD.Domain;
  6. using DDD.Domain.Arrange;
  7.  
  8. namespace DDD.Services
  9. {
  10. public class PlanArrangeService : NDJHService<PlanArrange>, IPlanArrangeService
  11. {
  12. private readonly IPlanArrangeRepository repository;
  13. private readonly ArrangeService service;
  14.  
  15. protected PlanArrangeService(IPlanArrangeRepository repository, ArrangeService service)
  16. : base(repository)
  17. {
  18. this.repository = repository;
  19. this.service = service;
  20. }
  21.  
  22. /// <summary>
  23. /// 查找可下发的批次列表
  24. /// </summary>
  25. /// <param name="xzqdm"></param>
  26. /// <returns></returns>
  27. public override IList<BatchModel> FindAllowSendBatches(string xzqdm)
  28. {
  29. if (string.IsNullOrEmpty(xzqdm)) throw new ArgumentNullException("xzqdm");
  30. if (!xzqdm.EndsWith("00")) //如果是县级用户,则不需要判断t.XFXZQDM != t.XZQDM这个条件
  31. {
  32. var list = FindBy(0, 0, xzqdm, ProjectStauts.Default).OrderBy(a => a.APPC).ToList();
  33. var query = from t in list
  34. group t by new { t.APPC, t.ND }
  35. into temp
  36. select new BatchModel
  37. {
  38. Batch = temp.Key.APPC,
  39. IsSent = false,
  40. Year = temp.Key.ND
  41. };
  42. return query.ToList();
  43.  
  44. }
  45. else
  46. {
  47. return base.FindAllowSendBatches(xzqdm);
  48. }
  49.  
  50. }
  51.  
  52. /// <summary>
  53. /// 查找计划安排列表
  54. /// </summary>
  55. /// <param name="year">年度</param>
  56. /// <param name="grade">指标级别</param>
  57. /// <param name="xzqdm">行政区代码</param>
  58. /// <returns></returns>
  59. public IList<PlanArrange> FindByDescendants(int year, string xzqdm, IndicatorGrade? grade = null)
  60. {
  61. if (string.IsNullOrEmpty(xzqdm)) throw new ArgumentNullException("xzqdm");
  62. var query = this.repository
  63. .Where(GetDistrictCodeExpr(xzqdm))
  64. .Where(grade.HasValue, a => a.ZBJB == grade.Value)
  65. .Where(year != 0, a => a.ND == year);
  66. if (xzqdm.EndsWith("0000"))
  67. {
  68. //省级用户可以查看国家安排、省级安排、市县级已下发的安排
  69. if (grade == IndicatorGrade.City || grade == IndicatorGrade.County)
  70. {
  71. query = query.Where(t=>t.Status == ProjectStauts.Sent);
  72. }
  73. }
  74. else if (xzqdm.EndsWith("00"))
  75. {
  76. //市级用户可以查看国家、省、县已下发的安排、市级安排
  77. if (grade != IndicatorGrade.City)
  78. {
  79. query = query.Where(t => t.Status == ProjectStauts.Sent);
  80. }
  81. }
  82. else
  83. {
  84. //县级用户可以查看国家、省、市已下发的安排、县级项目
  85. if (grade != IndicatorGrade.County)
  86. {
  87. query = query.Where(t => t.Status == ProjectStauts.Sent);
  88. }
  89. }
  90. return query.OrderBy(t => t.APPC).ToList();
  91. }
  92.  
  93. /// <summary>
  94. /// 行政区代码表达式
  95. /// </summary>
  96. /// <param name="xzqdm">一般为参数传递的值</param>
  97. /// <returns></returns>
  98. private Expression<Func<PlanArrange, bool>> GetDistrictCodeExpr(string xzqdm)
  99. {
  100. if (string.IsNullOrEmpty(xzqdm)) throw new ArgumentNullException("xzqdm");
  101. if (xzqdm.EndsWith("0000"))
  102. {
  103. var sub = xzqdm.Substring(0, 2);
  104. return d => d.XFXZQDM.Contains(sub);
  105. }
  106. else if (xzqdm.EndsWith("00"))
  107. {
  108. var sub = xzqdm.Substring(0, 4);
  109. return d => d.XFXZQDM.Contains(sub);
  110. }
  111. else
  112. {
  113. return d => d.XFXZQDM.Contains(xzqdm);
  114. }
  115. }
  116.  
  117. public override void Update(PlanArrange entity)
  118. {
  119. service.CheckUpdate(entity);
  120. base.Update(entity);
  121. }
  122.  
  123. public override void Register(PlanArrange entity, IList<PlanArrange> entities)
  124. {
  125. if (entity == null) throw new ArgumentNullException("entity");
  126. Validate(entity);
  127. Validate(entities);
  128. service.Register(entity, entities);
  129. repository.Add(entity);
  130. foreach (var item in entities)
  131. {
  132. repository.Add(item);
  133. }
  134. }
  135. }
  136. }

运用层代码2

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Linq.Expressions;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using DDD.Domain;
  8. using DDD.Domain.Indicator;
  9.  
  10. namespace DDD.Services
  11. {
  12. public class PlanIndicatorService : NDJHService<PlanIndicator>, IPlanIndicatorService
  13. {
  14. private readonly IPlanIndicatorRepository repository;
  15. private readonly IndicatorService service;
  16.  
  17. protected PlanIndicatorService(IPlanIndicatorRepository repository, IndicatorService service)
  18. : base(repository)
  19. {
  20. this.repository = repository;
  21. this.service = service;
  22. }
  23.  
  24. /// <summary>
  25. /// 查找指标列表(国家下发,省级发,市级下发)
  26. /// </summary>
  27. /// <param name="year">年度</param>
  28. /// <param name="xzqdm">下发行政区代码</param>
  29. /// <param name="grade">指标级别</param>
  30. /// <returns></returns>
  31. public IList<PlanIndicator> FindReceive(int year, string xzqdm)
  32. {
  33. if (string.IsNullOrEmpty(xzqdm)) throw new ArgumentNullException("xzqdm");
  34. return this.repository
  35. .Where(t => t.XFXZQDM != t.XZQDM)
  36. .Where(t => t.XFXZQDM == xzqdm)
  37. .Where(t => t.Status == ProjectStauts.Sent)
  38. .Where(year != 0, a => a.ND == year)
  39. .OrderBy(a => a.APPC).ToList();
  40. }
  41.  
  42. /// <summary>
  43. /// 查找预留指标列表(省级预留,市级预留)
  44. /// </summary>
  45. /// <param name="year">年度</param>
  46. /// <param name="xzqdm">行政区代码</param>
  47. /// <returns></returns>
  48. public IList<PlanIndicator> FindReserve(int year, string xzqdm)
  49. {
  50. if (string.IsNullOrEmpty(xzqdm)) throw new ArgumentNullException("xzqdm");
  51. return this.repository
  52. .Where(a => a.XFXZQDM == a.XZQDM)
  53. .Where(a => a.XZQDM == xzqdm)
  54. .Where(year != 0, a => a.ND == year)
  55. .OrderBy(a => a.APPC).ToList();
  56. }
  57.  
  58. /// <summary>
  59. /// 查找下发指标列表(下发市级,下发县级)
  60. /// </summary>
  61. /// <param name="year">年度</param>
  62. /// <param name="xzqdm">行政区代码</param>
  63. /// <returns></returns>
  64. public IList<PlanIndicator> FindSendTo(int year, string xzqdm)
  65. {
  66. if (string.IsNullOrEmpty(xzqdm)) throw new ArgumentNullException("xzqdm");
  67. return this.repository
  68. .Where(a => a.XFXZQDM != a.XZQDM)
  69. .Where(a => a.XZQDM == xzqdm)
  70. .Where(year != 0, a => a.ND == year)
  71. .OrderBy(a => a.APPC).ToList();
  72. }
  73.  
  74. /// <summary>
  75. /// 查找指定行政区下发的指标(预留+下发)
  76. /// </summary>
  77. /// <param name="status">状态</param>
  78. /// <param name="xzqdm">行政区代码</param>
  79. /// <returns></returns>
  80. public IList<PlanIndicator> FindSend(string xzqdm, ProjectStauts status)
  81. {
  82. if (string.IsNullOrEmpty(xzqdm)) throw new ArgumentNullException("xzqdm");
  83. return this.repository
  84. .Where(a => a.XZQDM == xzqdm)
  85. .Where(t => t.Status == status)
  86. .OrderBy(a => a.APPC).ToList();
  87. }
  88.  
  89. /// <summary>
  90. /// 统计预留指标
  91. /// </summary>
  92. /// <param name="year"></param>
  93. /// <param name="xzqdm"></param>
  94. /// <returns></returns>
  95. public IndicatorArea TotalReserveIndicator(int year, string xzqdm)
  96. {
  97. if (string.IsNullOrEmpty(xzqdm)) throw new ArgumentNullException("xzqdm");
  98. return repository.TotalReserveIndicator(year, xzqdm);
  99. }
  100.  
  101. /// <summary>
  102. /// 统计上级下发给下级指标(省-国家下发,市-省级下发,县-市级下发)
  103. /// </summary>
  104. /// <param name="year"></param>
  105. /// <param name="xzqdm"></param>
  106. /// <returns></returns>
  107. public IndicatorArea TotalReceiveIndicator(int year, string xzqdm)
  108. {
  109. if (string.IsNullOrEmpty(xzqdm)) throw new ArgumentNullException("xzqdm");
  110. return repository.TotalReceiveIndicator(year, xzqdm);
  111. }
  112.  
  113. /// <summary>
  114. /// 统计下发给下级的指标(省-市级下发,市-县级下发)
  115. /// </summary>
  116. /// <param name="year"></param>
  117. /// <param name="xzqdm"></param>
  118. /// <returns></returns>
  119. public IndicatorArea TotalSendToIndicator(int year, string xzqdm)
  120. {
  121. if (string.IsNullOrEmpty(xzqdm)) throw new ArgumentNullException("xzqdm");
  122. return repository.TotalSendToIndicator(year, xzqdm);
  123. }
  124.  
  125. public override void Update(PlanIndicator entity)
  126. {
  127. service.CheckUpdate(entity);
  128. base.Update(entity);
  129. }
  130.  
  131. public override void Register(PlanIndicator entity, IList<PlanIndicator> entities)
  132. {
  133. if (entity == null) throw new ArgumentNullException("entity");
  134. Validate(entity);
  135. Validate(entities);
  136. service.Register(entity, entities);
  137. repository.Add(entity);
  138. foreach (var item in entities)
  139. {
  140. repository.Add(item);
  141. }
  142. }
  143. }
  144. }

DDD领域驱动设计之运用层代码的更多相关文章

  1. C#进阶系列——DDD领域驱动设计初探(七):Web层的搭建

    前言:好久没更新博客了,每天被该死的业务缠身,今天正好一个模块完成了,继续来完善我们的代码.之前的六篇完成了领域层.应用层.以及基础结构层的部分代码,这篇打算搭建下UI层的代码. DDD领域驱动设计初 ...

  2. DDD领域驱动设计之领域基础设施层

    1.DDD领域驱动设计实践篇之如何提取模型 2.DDD领域驱动设计之聚合.实体.值对象 其实这里说的基础设施层只是领域层的一些接口和基类而已,没有其他的如日子工具等代码,仅仅是为了说明领域层的一些基础 ...

  3. DDD领域驱动设计初探(七):Web层的搭建

    前言:好久没更新博客了,每天被该死的业务缠身,今天正好一个模块完成了,继续来完善我们的代码.之前的六篇完成了领域层.应用层.以及基础结构层的部分代码,这篇打算搭建下UI层的代码. DDD领域驱动设计初 ...

  4. DDD 领域驱动设计-谈谈 Repository、IUnitOfWork 和 IDbContext 的实践(2)

    上一篇:<DDD 领域驱动设计-谈谈 Repository.IUnitOfWork 和 IDbContext 的实践(1)> 阅读目录: 抽离 IRepository 并改造 Reposi ...

  5. DDD 领域驱动设计-如何控制业务流程?

    上一篇:<DDD 领域驱动设计-如何完善 Domain Model(领域模型)?> 开源地址:https://github.com/yuezhongxin/CNBlogs.Apply.Sa ...

  6. DDD 领域驱动设计-如何完善 Domain Model(领域模型)?

    上一篇:<DDD 领域驱动设计-如何 DDD?> 开源地址:https://github.com/yuezhongxin/CNBlogs.Apply.Sample(代码已更新) 阅读目录: ...

  7. DDD领域驱动设计之领域服务

    1.DDD领域驱动设计实践篇之如何提取模型 2.DDD领域驱动设计之聚合.实体.值对象 3.DDD领域驱动设计之领域基础设施层 什么是领域服务,DDD书中是说,有些类或者方法,放实体A也不好,放实体B ...

  8. DDD 领域驱动设计-谈谈 Repository、IUnitOfWork 和 IDbContext 的实践(1)

    好久没写 DDD 领域驱动设计相关的文章了,嘎嘎!!! 这几天在开发一个新的项目,虽然不是基于领域驱动设计的,但我想把 DDD 架构设计的一些东西运用在上面,但发现了很多问题,这些在之前的短消息项目中 ...

  9. C#进阶系列——DDD领域驱动设计初探(一):聚合

    前言:又有差不多半个月没写点什么了,感觉这样很对不起自己似的.今天看到一篇博文里面写道:越是忙人越有时间写博客.呵呵,似乎有点道理,博主为了证明自己也是忙人,这不就来学习下DDD这么一个听上去高大上的 ...

随机推荐

  1. 线程池的使用ExecutorService

    private ExecutorService executorService = Executors.newFixedThreadPool(5); // 引入线程池来管理多线程 private vo ...

  2. avalon2学习教程15指令总结

    avalon的指令在上一节已经全部介绍完毕,当然有的语焉不详,如ms-js.本节主要总结我对这方面的思考与探索. MVVM的成功很大一语分是来自于其指令,或叫绑定.让操作视图的功能交由形形式式的指令来 ...

  3. asp.net前台绑定时间格式时,定义时间格式

    <%#Eval("news_time","{0:yyyy-MM-dd}") %><%#((DateTime)Eval("news_t ...

  4. JavaScript中的Map

    1.首先,在新版本的浏览器中,已经实现了对Map的原生支持:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Glob ...

  5. 比较详细PHP生成静态页面教程

    一,PHP脚本与动态页面. PHP脚本是一种服务器端脚本程序,可通过嵌入等方法与HTML文件混合, 也可以类,函数封装等形式,以模板的方式对用户请求进行处理.无论以何种方式,它的基本原理是这样的.由客 ...

  6. C语言 malloc calloc realloc alloc 在分配内存时的 区别

    malloc : 向堆申请分配内存,不初始化 calloc  : 向堆申请分配内存,初始化为0 realloc:  向堆申请分配内存,可调整大小 alloc   :   向栈申请内存,不需手动释放

  7. centos 7 u盘安装

    centos 7 u盘安装 http://www.centoscn.com/image-text/setup/2014/0724/3342.html

  8. [转] Python包和类的基本用法

    http://blog.csdn.net/liukang325/article/details/46724365 建立一个文件夹filePackage 在filePackage 文件夹内创建 __in ...

  9. iOS /* */多个嵌套解决

    解决办法 #if 0 /* */ #endif

  10. js浮点数计算问题 + 金额大写转换

    一 js浮点数计算问题解决方案: 1.使用 NumberObject.toFixed(num) 方法 toFixed() 方法可把 Number 四舍五入为指定小数位数的数字. 2.较精度计算浮点数 ...