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

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

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

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

5、整体DEMO代码

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

运用层代码1

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using DDD.Domain;
using DDD.Domain.Arrange; namespace DDD.Services
{
public class PlanArrangeService : NDJHService<PlanArrange>, IPlanArrangeService
{
private readonly IPlanArrangeRepository repository;
private readonly ArrangeService service; protected PlanArrangeService(IPlanArrangeRepository repository, ArrangeService service)
: base(repository)
{
this.repository = repository;
this.service = service;
} /// <summary>
/// 查找可下发的批次列表
/// </summary>
/// <param name="xzqdm"></param>
/// <returns></returns>
public override IList<BatchModel> FindAllowSendBatches(string xzqdm)
{
if (string.IsNullOrEmpty(xzqdm)) throw new ArgumentNullException("xzqdm");
if (!xzqdm.EndsWith("00")) //如果是县级用户,则不需要判断t.XFXZQDM != t.XZQDM这个条件
{
var list = FindBy(0, 0, xzqdm, ProjectStauts.Default).OrderBy(a => a.APPC).ToList();
var query = from t in list
group t by new { t.APPC, t.ND }
into temp
select new BatchModel
{
Batch = temp.Key.APPC,
IsSent = false,
Year = temp.Key.ND
};
return query.ToList(); }
else
{
return base.FindAllowSendBatches(xzqdm);
} } /// <summary>
/// 查找计划安排列表
/// </summary>
/// <param name="year">年度</param>
/// <param name="grade">指标级别</param>
/// <param name="xzqdm">行政区代码</param>
/// <returns></returns>
public IList<PlanArrange> FindByDescendants(int year, string xzqdm, IndicatorGrade? grade = null)
{
if (string.IsNullOrEmpty(xzqdm)) throw new ArgumentNullException("xzqdm");
var query = this.repository
.Where(GetDistrictCodeExpr(xzqdm))
.Where(grade.HasValue, a => a.ZBJB == grade.Value)
.Where(year != 0, a => a.ND == year);
if (xzqdm.EndsWith("0000"))
{
//省级用户可以查看国家安排、省级安排、市县级已下发的安排
if (grade == IndicatorGrade.City || grade == IndicatorGrade.County)
{
query = query.Where(t=>t.Status == ProjectStauts.Sent);
}
}
else if (xzqdm.EndsWith("00"))
{
//市级用户可以查看国家、省、县已下发的安排、市级安排
if (grade != IndicatorGrade.City)
{
query = query.Where(t => t.Status == ProjectStauts.Sent);
}
}
else
{
//县级用户可以查看国家、省、市已下发的安排、县级项目
if (grade != IndicatorGrade.County)
{
query = query.Where(t => t.Status == ProjectStauts.Sent);
}
}
return query.OrderBy(t => t.APPC).ToList();
} /// <summary>
/// 行政区代码表达式
/// </summary>
/// <param name="xzqdm">一般为参数传递的值</param>
/// <returns></returns>
private Expression<Func<PlanArrange, bool>> GetDistrictCodeExpr(string xzqdm)
{
if (string.IsNullOrEmpty(xzqdm)) throw new ArgumentNullException("xzqdm");
if (xzqdm.EndsWith("0000"))
{
var sub = xzqdm.Substring(0, 2);
return d => d.XFXZQDM.Contains(sub);
}
else if (xzqdm.EndsWith("00"))
{
var sub = xzqdm.Substring(0, 4);
return d => d.XFXZQDM.Contains(sub);
}
else
{
return d => d.XFXZQDM.Contains(xzqdm);
}
} public override void Update(PlanArrange entity)
{
service.CheckUpdate(entity);
base.Update(entity);
} public override void Register(PlanArrange entity, IList<PlanArrange> entities)
{
if (entity == null) throw new ArgumentNullException("entity");
Validate(entity);
Validate(entities);
service.Register(entity, entities);
repository.Add(entity);
foreach (var item in entities)
{
repository.Add(item);
}
}
}
}

运用层代码2

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using DDD.Domain;
using DDD.Domain.Indicator; namespace DDD.Services
{
public class PlanIndicatorService : NDJHService<PlanIndicator>, IPlanIndicatorService
{
private readonly IPlanIndicatorRepository repository;
private readonly IndicatorService service; protected PlanIndicatorService(IPlanIndicatorRepository repository, IndicatorService service)
: base(repository)
{
this.repository = repository;
this.service = service;
} /// <summary>
/// 查找指标列表(国家下发,省级发,市级下发)
/// </summary>
/// <param name="year">年度</param>
/// <param name="xzqdm">下发行政区代码</param>
/// <param name="grade">指标级别</param>
/// <returns></returns>
public IList<PlanIndicator> FindReceive(int year, string xzqdm)
{
if (string.IsNullOrEmpty(xzqdm)) throw new ArgumentNullException("xzqdm");
return this.repository
.Where(t => t.XFXZQDM != t.XZQDM)
.Where(t => t.XFXZQDM == xzqdm)
.Where(t => t.Status == ProjectStauts.Sent)
.Where(year != 0, a => a.ND == year)
.OrderBy(a => a.APPC).ToList();
} /// <summary>
/// 查找预留指标列表(省级预留,市级预留)
/// </summary>
/// <param name="year">年度</param>
/// <param name="xzqdm">行政区代码</param>
/// <returns></returns>
public IList<PlanIndicator> FindReserve(int year, string xzqdm)
{
if (string.IsNullOrEmpty(xzqdm)) throw new ArgumentNullException("xzqdm");
return this.repository
.Where(a => a.XFXZQDM == a.XZQDM)
.Where(a => a.XZQDM == xzqdm)
.Where(year != 0, a => a.ND == year)
.OrderBy(a => a.APPC).ToList();
} /// <summary>
/// 查找下发指标列表(下发市级,下发县级)
/// </summary>
/// <param name="year">年度</param>
/// <param name="xzqdm">行政区代码</param>
/// <returns></returns>
public IList<PlanIndicator> FindSendTo(int year, string xzqdm)
{
if (string.IsNullOrEmpty(xzqdm)) throw new ArgumentNullException("xzqdm");
return this.repository
.Where(a => a.XFXZQDM != a.XZQDM)
.Where(a => a.XZQDM == xzqdm)
.Where(year != 0, a => a.ND == year)
.OrderBy(a => a.APPC).ToList();
} /// <summary>
/// 查找指定行政区下发的指标(预留+下发)
/// </summary>
/// <param name="status">状态</param>
/// <param name="xzqdm">行政区代码</param>
/// <returns></returns>
public IList<PlanIndicator> FindSend(string xzqdm, ProjectStauts status)
{
if (string.IsNullOrEmpty(xzqdm)) throw new ArgumentNullException("xzqdm");
return this.repository
.Where(a => a.XZQDM == xzqdm)
.Where(t => t.Status == status)
.OrderBy(a => a.APPC).ToList();
} /// <summary>
/// 统计预留指标
/// </summary>
/// <param name="year"></param>
/// <param name="xzqdm"></param>
/// <returns></returns>
public IndicatorArea TotalReserveIndicator(int year, string xzqdm)
{
if (string.IsNullOrEmpty(xzqdm)) throw new ArgumentNullException("xzqdm");
return repository.TotalReserveIndicator(year, xzqdm);
} /// <summary>
/// 统计上级下发给下级指标(省-国家下发,市-省级下发,县-市级下发)
/// </summary>
/// <param name="year"></param>
/// <param name="xzqdm"></param>
/// <returns></returns>
public IndicatorArea TotalReceiveIndicator(int year, string xzqdm)
{
if (string.IsNullOrEmpty(xzqdm)) throw new ArgumentNullException("xzqdm");
return repository.TotalReceiveIndicator(year, xzqdm);
} /// <summary>
/// 统计下发给下级的指标(省-市级下发,市-县级下发)
/// </summary>
/// <param name="year"></param>
/// <param name="xzqdm"></param>
/// <returns></returns>
public IndicatorArea TotalSendToIndicator(int year, string xzqdm)
{
if (string.IsNullOrEmpty(xzqdm)) throw new ArgumentNullException("xzqdm");
return repository.TotalSendToIndicator(year, xzqdm);
} public override void Update(PlanIndicator entity)
{
service.CheckUpdate(entity);
base.Update(entity);
} public override void Register(PlanIndicator entity, IList<PlanIndicator> entities)
{
if (entity == null) throw new ArgumentNullException("entity");
Validate(entity);
Validate(entities);
service.Register(entity, entities);
repository.Add(entity);
foreach (var item in entities)
{
repository.Add(item);
}
}
}
}

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. JavaScript和Java之间的关系

    今天来简单而又详细地说说JavaScript和Java的关系. 开门见山总结性一句话,它们之间的关系 = 雷锋和雷峰塔之间的关系,换句话说:它们之间没什么关系. 但往往有不少初学者甚至中级者认为它们之 ...

  2. C 最熟悉的陌生人 (纪念当年就读的梅州市江南高级中学)

    最熟悉的陌生人 作者:张慧桥 “枪与玫瑰” 我送走了“蝶恋花”,犹有一种身在梦中的感觉,昨晚的宿醉让我只觉得头晕乎乎的很不舒服,想想自己连澡都还没洗呢,便去洗了个冷水澡. 煮了杯浓浓的咖啡喝了下去,我 ...

  3. 来个linq to js

    说这个话题之前,我们来讲一下C#的linq  语法.在C#里面我们会对列表进行操作,如OrderBy(p=>p.property),Where(p=>p.property==..) 括号里 ...

  4. Linux下修改网卡的mac地址

    方法1: # ifconfig ethX down # ifconfig ethX hw ether NEW_MAC_ADDR # ifconfig ethX up 但是这样重启后就失效了,需要再敲一 ...

  5. ansibleplaybook的使用

    1.简单格式要求 [root@ansibleserver ansible]# cat nagios.yml --- - hosts: nagiosserver tasks: - name: ensur ...

  6. git 配置多个SSH-Key(转)

    摘要 我们在日常工作中会遇到公司有个gitlab,还有些自己的一些项目放在github上.这样就导致我们要配置不同的ssh-key对应不同的环境. 目录[-] 1,生成一个公司用的SSH-Key 2, ...

  7. Lodop打印控件在页面如何使用

    Lodop打印控件部署到web服务器简单,在页面的使用方法也简单,是非常容易和方便使用的打印控件.客户端本地打印角色(即用户访问网站后 用自己链接的打印机进行客户端本地打印),步骤很少,部署简单:Lo ...

  8. XJ模拟noip赛1

    什么都不说—— 成功打出 G-G!

  9. 收藏nginx学习

    http://blog.csdn.net/u012186351/article/details/50605672 http://blog.csdn.net/qq_25371579/article/de ...

  10. ntpdate 正确的做法

    网上很多搜到的资料都是过时的,主要是时间服务器不能用,不管是国内的还是国外的 1. yum -y install ntp ntpdate 2. 在/etc/crontab中,加入: 0 0 0 * 1 ...