NLayerAppV3--.net Core2实现的DDD分层架构
虽然每天的工作都是CURD、还是使用着传统的三层架构、使用着.net Framework,但是这并不能影响我学习DDD和.net core。
总是希望软件在应对复杂多变的场景时能够游刃有余,在解决问题时能够多一种选择。
很早就有关注大神dax.net的NLayerApp系列博文https://www.cnblogs.com/daxnet/category/304141.html
近期入坑.net core,看了进击的辣条的文章Asp.Net Core微服务初体验,很有收获,感谢感谢。
抽时间读了下NLayerAppV3项目的源码,Github地址:https://github.com/cesarcastrocuba/nlayerappv3
分享下体会,希望相互交流学习,谢谢!
1、项目简介
NLayerAppV3是一个使用.net 2.1实现的经典DDD的分层架构的项目。
NLayerAppV3是在NLayerAppV2的基础上,使用.net core2.1进行重新构建的;它包含了开发人员和架构师都可以重用的DDD层;以银行和博客上下文示例。
2、项目结构
放一张DDD风格架构l图。主要分为四层:表现层、应用层、领域层和基础结构层。
详细的各层的含义可以查看dax.net的文章https://www.cnblogs.com/daxnet/archive/2011/05/10/2042095.html
1.1-Presentation(表现层)
系统和用户的交互层。UI展示给终端用户、收集用户的反馈信息。
1.2-Distributed Services(分布式服务层)
为应用程序提供远程访问;如果是http协议,一般设计为WebApi。
1.2.1-Seedwork --DistributedServices.Seedwork
分布式服务的Controller、Filter等
1.2.2-MainBoundedContext
--DistributedServices.MainBoundedContext
以银行的业务示例,构建上下文、对外提供WebApi服务,结合Swagger UI
--DistributedServices.MainBoundedContext.Tests
DistributedServices.MainBoundedContext的测试项目
1.2.3-BlogContext
--DistributedServices.BlogBoundedContext
以博客业务示例,构建上下文,对外提供WebApi服务,结合Swagger UI
--DistributedServices.BlogBoundedContext.Tests
DistributedServices.BlogBoundedContext项目的测试项目
1.3-Application(应用层)
协调领域模型与其它应用、包括事务调度、UOW、数据转换等。
主要作用:通过仓储来访问持久层;对不同领域的数据组织整理;协调领域对象之间、领域对象与基础层的协作关系;应用服务等
1.3.1-Seedwork --Application.Seedwork
应用层共用接口、实现的封装
1.3.2-MainBoundedContext
--Application.MainBoundedContext
业务模块的应用层服务接口和实现
--Application.MainBoundedContext.DTO
应用层业务模块的数据转换等
--Application.MainBoundedContext.Tests
Application.MainBoundedContext的测试项目
1.3.3-BlogBoundedContext
同1.3.2,不同的是业务换为博客业务
1.4-Domain(领域层)
展现业务/领域逻辑、业务处理状态,以及实现业务规则,它同时也包含了领域对象的状态信息。
1.4.1-Seedwork
--Domain.Seedwork
领域层实体基类、仓储接口、UOW接口、值对象基类、规约等
--Domain.Seedwork.Tests
Domain.Seedwork的测试项目
1.4.2-MainBoundedContext
--Domain.MainBoundedContext
实体、值对象、领域服务、聚合根、聚合及工厂
--Domain.MainBoundedContext.Tests
Domain.MainBoundedContext的测试项目
1.4.3-BlogBoundedContext
同1.4.2 业务逻辑换成了博客
1.5-Infrastructure(基础设施层)
1.5.1-Data
为应用程序的数据存取提供服务,它可以是应用程序本身的持久化机制,也可以是外部系统提供的数据访问的Web Service等
--Infrastructure.Data.Seedwork
UOW的实现基类、仓储的实现基类
--Infrastructure.Data.MainBoundedContext
UOW的实现、仓储的实现
--Infrastructure.Data.MainBoundedContext.Tests
Infrastructure.Data.MainBoundedContext的测试项目
1.5.2-CrossCutting
该层提供了能被其它各层访问的通用技术框架,比如异常捕获与处理、日志、认证、授权、验证、跟踪、监视、缓存等等。
--Infrastructure.Crosscutting
适配器、国际化、验证等接口的封装
--Infrastructure.Crosscutting.NetFramework
适配器、国际化、验证等实现、国际化依赖的资源
--Infrastructure.Crosscutting.Tests
Infrastructure.Crosscutting的测试项目
3、示例
以DistributedServices.MainBoundedContext项目的BankAccounts的转账api示例,说明下我的理解
[HttpPut]
public void PerformTransfer([FromBody]BankAccountDTO from, [FromBody]BankAccountDTO to, [FromBody]decimal amount)
{
_bankAppService.PerformBankTransfer(from, to, amount);
}
_bankAppService通过构造函数注入。
readonly IBankAppService _bankAppService; public BankAccounts(IBankAppService bankAppService)
{
_bankAppService = bankAppService;
}
IBankAppService是应用层的服务接口
对应的应用层有接口的实现BankAppService
public BankAppService(IBankAccountRepository bankAccountRepository, // the bank account repository dependency
ICustomerRepository customerRepository, // the customer repository dependency
IBankTransferService transferService,
ILogger<BankAppService> logger)
{
//check preconditions
if (bankAccountRepository == null)
throw new ArgumentNullException("bankAccountRepository"); if (customerRepository == null)
throw new ArgumentNullException("customerRepository"); if (transferService == null)
throw new ArgumentNullException("trasferService"); _bankAccountRepository = bankAccountRepository;
_customerRepository = customerRepository;
_transferService = transferService; _logger = logger;
_resources = LocalizationFactory.CreateLocalResources(); }
BankAppService通过构造函数注入了领域层的银行账号仓储IBankAccountRepository和客户仓储ICustomerRepository、转账服务等,全部依赖于接口。
public void PerformBankTransfer(BankAccountDTO fromAccount, BankAccountDTO toAccount, decimal amount)
{
//Application-Logic Process:
// 1º Get Accounts objects from Repositories
// 2º Start Transaction
// 3º Call PerformTransfer method in Domain Service
// 4º If no exceptions, commit the unit of work and complete transaction if (BankAccountHasIdentity(fromAccount)
&&
BankAccountHasIdentity(toAccount))
{
var source = _bankAccountRepository.Get(fromAccount.Id);
var target = _bankAccountRepository.Get(toAccount.Id); if (source != null & target != null) // if all accounts exist
{
using (TransactionScope scope = new TransactionScope())
{
//perform transfer
_transferService.PerformTransfer(amount, source, target); //comit unit of work
_bankAccountRepository.UnitOfWork.Commit(); //complete transaction
scope.Complete();
}
}
else
_logger.LogError(_resources.GetStringResource(LocalizationKeys.Application.error_CannotPerformTransferInvalidAccounts));
}
else
_logger.LogError(_resources.GetStringResource(LocalizationKeys.Application.error_CannotPerformTransferInvalidAccounts)); }
实现转账的功能,输入参数都是Dto对象,通过AutoMapper或者其它映射工具完成数据转换;通过仓储访问聚合,获取源和目标账号信息、开启事务,UOW提交转账操作。
DistributedServices.MainBoundedContext的StartUp中注册IOC
仓储、领域服务、应用层服务、适配器、国际化、验证、Swagger UI等。
运行项目
在DistributedServices.MainBoundedContext目录下打开cmd命令,输入dotnet restore,完成之后,输入dotnet run
运行结果:
4、想法和计划
跟.net core microservice结合
使用ocelot搭建服务网关、结合identityserver4实现授权认证;polly服务熔断;限流;consul服务发现;Appolo配置中心;Skywalking追踪结果。
NLayerAppV3--.net Core2实现的DDD分层架构的更多相关文章
- 应用程序框架实战十八:DDD分层架构之聚合
前面已经介绍了DDD分层架构的实体和值对象,本文将介绍聚合以及与其高度相关的并发主题. 我在之前已经说过,初学者第一步需要将业务逻辑尽量放到实体或值对象中,给实体“充血”,这样可以让业务逻辑高度内聚, ...
- 应用程序框架实战十七:DDD分层架构之值对象(层超类型篇)
上一篇介绍了值对象的基本概念,得到了一些朋友的支持,另外也有一些朋友提出了不同意见.这其实是很自然的事情,设计本来就充满了各种可能性,没有绝对正确的做法,只有更好的实践.但是设计与实践的好与坏,对于不 ...
- 应用程序框架实战十六:DDD分层架构之值对象(介绍篇)
前面介绍了DDD分层架构的实体,并完成了实体层超类型的开发,同时提供了验证方面的支持.本篇将介绍另一个重要的构造块——值对象,它是聚合中的主要成分. 如果说你已经在使用DDD分层架构,但你却从来没有使 ...
- 应用程序框架实战十五:DDD分层架构之领域实体(验证篇)
在应用程序框架实战十四:DDD分层架构之领域实体(基础篇)一文中,我介绍了领域实体的基础,包括标识.相等性比较.输出实体状态等.本文将介绍领域实体的一个核心内容——验证,它是应用程序健壮性的基石.为了 ...
- 应用程序框架实战十四:DDD分层架构之领域实体(基础篇)
上一篇,我介绍了自己在DDD分层架构方面的一些感想,本文开始介绍领域层的实体,代码主要参考自<领域驱动设计C#2008实现>,另外参考了网上找到的一些示例代码. 什么是实体 由标识来区分的 ...
- 应用程序框架实战十三:DDD分层架构之我见
前面介绍了应用程序框架的一个重要组成部分——公共操作类,并提供了一个数据类型转换公共操作类作为示例进行演示.下面准备介绍应用程序框架的另一个重要组成部分,即体系架构支持.你不一定要使用DDD这样的架构 ...
- 应用程序框架实战十三:DDD分层架构之我见(转)
前面介绍了应用程序框架的一个重要组成部分——公共操作类,并提供了一个数据类型转换公共操作类作为示例进行演示.下面准备介绍应用程序框架的另一个重要组成部分,即体系架构支持.你不一定要使用DDD这样的架构 ...
- DDD分层架构的进化
.NET逻辑分层架构演示:DDD分层架构的进化 概述: 架构是高层的设计,如果设计和理解有误,必将在实现时带来各种问题.架构又是最稳定的,不会因为各种具体技术的依赖,如各种UI框架.ORM框架.I ...
- DDD分层架构之仓储
DDD分层架构之仓储(层超类型基础篇) 前一篇介绍了仓储的基本概念,并谈了我对仓储的一些认识,本文将实现仓储的基本功能. 仓储代表聚合在内存中的集合,所以仓储的接口需要模拟得像一个集合.仓储中有很多操 ...
随机推荐
- MyBatis配置数据源的两种方式
---------------------siwuxie095 MyBatis 配置数据源的两种方式 1.配置方 ...
- 使用生活实例理解Asp.net运行时
学习编程语言,掌握面向对象的编程思想尤为重要,一旦理解了面向对象的这种概念,那么好些地方拿到生活中去理解,就容易的多了.书本上的枯燥干涩的语言,对于好多人来说,即难懂,更难长时间牢牢记得.但是编程语言 ...
- 编辑距离12 · Edit Distance12
[抄题]: 给出两个单词word1和word2,计算出将word1 转换为word2的最少操作次数. 你总共三种操作方法: 插入一个字符 删除一个字符 替换一个字符 [思维问题]: [一句话思路]: ...
- php的无刷新实现方法
方法一: 我们通过http的204状态码,页面不跳转. 1.html代码如下: <!DOCTYPE HTML> <html lang="zh-CN"> &l ...
- Linux tcpdump命令
一.简介 用简单的话来定义tcpdump,就是:dump the traffic on a network,根据使用者的定义对网络上的数据包进行截获的包分析工具. tcpdump可以将网络中传送的数据 ...
- Fully Update And Upgrade Offline Debian-based Systems
Let us say, you have a system (Windows or Linux) with high-speed Internet connection at work and a D ...
- 利用HBuilder打包前端开发webapp为apk
转载 标签: apk / 打包 / vue 现在的前端开发可谓是,百花齐放啦,什么都可以做,只有想不到没有做不到的,今天就简单的介绍用vue,ng或者是react开发的单页应用如何打包为apk,在移动 ...
- stl学习记录(1)
Effective STL 中文版学习记录 条款4 判断容器是否为空 使用empty而不是size().size()操作在实现上不是一个时间常数操作条款5 尽量使用区间成员函数代替它们的单元素兄弟.S ...
- sqlldr 笔记
表结构 CREATE table sqlloader_test ( f1 char(20), f2 char(20), f3 number(16), f4 date ); 数据文件data.csv 1 ...
- 2018.10.12 bzoj4712: 洪水(树链剖分)
传送门 树链剖分好题. 考虑分开维护重儿子和轻儿子的信息. 令f[i]f[i]f[i]表示iii为根子树的最优值,h[i]h[i]h[i]表示iii重儿子的最优值,g[i]g[i]g[i]表示iii所 ...