NLayerAppV3--DDD之领域层
回顾:NLayerAppV3是一个使用.net 2.1实现的经典DDD的分层架构的项目。
NLayerAppV3是在NLayerAppV2的基础上,使用.net core2.1进行重新构建的;它包含了开发人员和架构师都可以重用的DDD层。
Github地址:https://github.com/cesarcastrocuba/nlayerappv3
上一篇,介绍了NLayerAppV3项目Infrastructure(基础设施层)的Cross-Cutting部分,文章地址:https://www.cnblogs.com/net-yuan/p/NLayerAppV3-Infrastructure_CrossCutting.html
NLayerAppV3的基础结构层一共分为两个部分。处理数据相关的基础组件Data和Cross-Cutting的基础组件。
处理数据相关的基础组件Data主要包含UOW和仓储的实现;
Cross-Cutting的基础组件目前主要包含数据适配器、国际化、验证;
这篇本来应该介绍Infrastructure(基础设施层)的Data部分。
可是仓储的具体实现是放在基础结构层的,而仓储的接口则是放在领域模型层的。
所以,我们就先介绍领域层Domain。
NLayerAppV3项目的Domain(领域层)分为两个部分:Seedwork和BoundedContext
Seedwork部分定义了实体的契约、实体的基类、值对象的基类、仓储的契约、UOW的契约、规约等。
BoundedContext部分定义了聚合相关,聚合、值对象、规约的具体实现、仓储的契约、领域服务等。
以下描述引用自何老大的博文:
聚合包装一组高度相关的对象,作为一个数据修改的单元。
聚合最外层的对象称为聚合根,它是一个实体。聚合根划分出一个清晰的边界,聚合根外部的对象,不能直接访问聚合根内部对象,如果需要访问内部对象,必须首先访问聚合根,再导航到聚合的内部对象。
聚合代表很强的包含关系,聚合内部的对象脱离了聚合,应该是毫无意义的,或不是你真正关注的,它是聚合的一个组成部分,这与UML中的组成聚合概念相近。
有关聚合的相关知识可以查看何老大的博文 https://www.cnblogs.com/xiadao521/p/4141904.html
以BankAccount聚合来看,BankAccount是聚合根,包含卡号BankAccountNumber这样的值对象,BankAccountNumber由国家或者地区银行编号、检查位等构成;Balance金额、Locked是否锁定、Customer用户实体、BankAccountActivity账户活动的集合等等、还包含锁定、解锁、存款等行为。这是一个充血的模型。
BankAccountFactory是创建聚合BankAccount的工厂,它负责创建BankAccount。
BankAccountSpecifications封装了BankAccount的查询规约
public static class BankAccountSpecifications
{
/// <summary>
/// Specification for bank accounts with number like to <paramref name="ibanNumber"/>
/// </summary>
/// <param name="ibanNumber">The bank account number</param>
/// <returns>Associated specification</returns>
public static ISpecification<BankAccount> BankAccountIbanNumber(string ibanNumber)
{
Specification<BankAccount> specification = new TrueSpecification<BankAccount>(); if (!String.IsNullOrWhiteSpace(ibanNumber))
{
specification &= new DirectSpecification<BankAccount>((b) => b.Iban
.ToLower()
.Contains(ibanNumber.ToLower()));
} return specification;
}
}
IBankAccountRepository提供了BankAccount的仓储契约
IBankTransferService提供了转账的领域服务契约,有一个转账方法
void PerformTransfer(decimal amount, BankAccount originAccount, BankAccount destinationAccount);
BankTransferService实现了IBankTransferService
实现了转账领域服务的逻辑。
public void PerformTransfer(decimal amount, BankAccount originAccount, BankAccount destinationAccount)
{
if (originAccount != null && destinationAccount != null)
{
var messages = LocalizationFactory.CreateLocalResources(); if (originAccount.BankAccountNumber == destinationAccount.BankAccountNumber) // if transfer in same bank account
throw new InvalidOperationException(messages.GetStringResource(LocalizationKeys.Domain.exception_CannotTransferMoneyWhenFromIsTheSameAsTo)); // Check if customer has required credit and if the BankAccount is not locked
if (originAccount.CanBeWithdrawed(amount))
{
//Domain Logic
//Process: Perform transfer operations to in-memory Domain-Model objects
// 1.- Charge money to origin acc
// 2.- Credit money to destination acc //Charge money
originAccount.WithdrawMoney(amount, string.Format(messages.GetStringResource(LocalizationKeys.Domain.messages_TransactionFromMessage), destinationAccount.Id)); //Credit money
destinationAccount.DepositMoney(amount, string.Format(messages.GetStringResource(LocalizationKeys.Domain.messages_TransactionToMessage), originAccount.Id));
}
else
throw new InvalidOperationException(messages.GetStringResource(LocalizationKeys.Domain.exception_BankAccountCannotWithdraw));
}
}
参考: dax.net https://www.cnblogs.com/daxnet/archive/2011/06/07/2074451.html
何镇汐 https://www.cnblogs.com/xiadao521/p/4141904.html
NLayerAppV3--DDD之领域层的更多相关文章
- [Abp vNext 源码分析] - 5. DDD 的领域层支持(仓储、实体、值对象)
一.简要介绍 ABP vNext 框架本身就是围绕着 DDD 理念进行设计的,所以在 DDD 里面我们能够见到的实体.仓储.值对象.领域服务,ABP vNext 框架都为我们进行了实现,这些基础设施都 ...
- Java开发架构篇:DDD模型领域层决策规则树服务设计
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 在上一章节介绍了领域驱动设计的基本概念以及按照领域驱动设计的思想进行代码分层,但是仅 ...
- DDD~领域层
回到目录 再论Domain与Infrastructure 在面向领域的设计中,领域层(Domain)实现上是位于最底层的,其它层有对它的引用,包括基础设施层(Infrastructure)也是去引用领 ...
- 【DDD】领域驱动设计实践 —— UI层实现
前面几篇blog主要介绍了DDD落地架构及业务建模战术,后续几篇blog会在此基础上,讲解具体的架构实现,通过完整代码demo的形式,更好地将DDD的落地方案呈现出来.本文是架构实现讲解的第一篇,主要 ...
- 【DDD】领域驱动设计实践 —— Application层实现
本文是DDD框架实现讲解的第二篇,主要介绍了DDD的Application层的实现,详细讲解了service.assemble的职责和实现.文末附有github地址.相比于<领域驱动设计> ...
- 【DDD】领域驱动设计实践 —— Domain层实现
本文是DDD框架实现讲解的第三篇,主要介绍了DDD的Domain层的实现,详细讲解了entity.value object.domain event.domain service的职责,以及如何识别出 ...
- DDD实战进阶第一波(五):开发一般业务的大健康行业直销系统(实现产品上下文领域层)
从这篇文章开始,我们根据前面的DDD理论与DDD框架的约束,正式进入直销系统案例的开发. 本篇文章主要讲产品上下文中的领域层的主要实现,先简单讲下业务方面的需求:产品SPU与产品SKU,产品SPU主要 ...
- ABP领域层
1.实体Entites 1.1 概念 实体是DDD(领域驱动设计)的核心概念之一. 实体是具有唯一标识的ID且存储在数据库总.实体通常被映射成数据库中的一个表. 在ABP中,实体继承自Entity类. ...
- 我的“第一次”,就这样没了:DDD(领域驱动设计)理论结合实践
写在前面 插一句:本人超爱落网-<平凡的世界>这一期,分享给大家. 阅读目录: 关于DDD 前期分析 框架搭建 代码实现 开源-发布 后记 第一次听你,清风吹送,田野短笛:第一次看你,半弯 ...
随机推荐
- impulse···········
impulse - Bing dictionary US['ɪm.pʌls]UK['ɪmpʌls] n.冲动:冲量:推动力:刺激 v.推动 网络脉冲:冲击 变形Plural Form:impulses ...
- Passing the Message
Passing the Message http://acm.hdu.edu.cn/showproblem.php?pid=3410 Time Limit: 2000/1000 MS (Java/Ot ...
- python进程之间修改数据[Manager]与进程池[Pool]
#前面的队列Queue和管道Pipe都是仅仅能再进程之间传递数据,但是不能修改数据,今天我们学习的东西就可以在进程之间同时修改一份数据 #Mnager就可以实现 import multiprocess ...
- [leetcode]125. Valid Palindrome判断回文串
Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignori ...
- php 账号不能同时登陆,当其它地方登陆时,当前账号失效
解决的思路是每当用户登陆时我们必需记录当前的用户id和session_id,如果有人在其它地方用此账号登陆时,我们把此用户id对应的session_id的session文件删除,并重新记录当前的ses ...
- vi编辑时出现E325:ATTENTION
我们用vi编辑文件时,系统会提示E325:ATTENTION. 这是由于在编辑该文件的时候异常退出了,因为vi在编辑文件时会创建一个交换文件swap file以保证文件的安全性. 但是每次打开文件时都 ...
- SVN版本冲突中 Files 的值“ < < < < < < < .mine”无效路径中具有非法字符的解决办法
.NET 中 SVN版本冲突中 Files 的值“ < < < < < < < .mine”无效路径中具有非法字符的解决办法: 一. 1.将项目逐个进行编译, ...
- Tomcat的杂七杂八
localhost_access_log.2016-01-15.txt 原来这里面有访问记录. /logs/catalina.2016-01-22.log 这里有显示失败的信息 2016-01-23 ...
- jquery panel加载(dialog加载类似)
项目情况: 主页面用引用了公共头文件(包含easui.min.js),使用easyui的dialog(href方式)打开窗口(被打开的窗口页面是纯html片段,无body元素等,也引入了公共头文件), ...
- Perl的调试模式熟悉和应用
perl -d file.pl perl -c file.pl DB<1> hList/search source lines: Control script ...