当前位置:网站首页>基于ABP实现DDD--领域逻辑和应用逻辑
基于ABP实现DDD--领域逻辑和应用逻辑
2022-07-26 18:23:00 【JavaMonsterr】
本文主要介绍了多应用层的问题,包括原因和实现。通过理解介绍了如何区分领域逻辑和应用逻辑,哪些是正确的实践,哪些是不推荐的或者错误的实践。
一.多应用层的问题
1.多应用层介绍
不知道你们是否会遇到一种情况,通过ABP构建了一个后端的API项目,刚开始是为Web端项目(比如,Vue)提供后端接口服务的,随着项目的发展和业务的复杂,增加了移动端的App,或者公众号、小程序等,这样不仅要为Web端提供API服务,而且还需要为移动端的App,或者公众号、小程序等提供API服务。这个场景就是多应用层的问题。也就是说你现在需要构建一个有多个应用程序的系统了:

- Web应用程序 :比如使用的ASP.NET Core MVC技术,主要用来给用户展示产品,游客模式是可以查看产品的,并不需要登录和验证。
- 后端管理应用程序 :比如前端是Vue,后端的ASP.NET Core API,主要用来对产品进行增删改等操作。
- 移动应用程序 :比如前端是uni-app,后端是ASP.NET Core API,通过REST接口和后端通信。
2.多应用层例子
由于业务的复杂性,每个应用系统都有自己的不同应用服务方法,不同的输入和输出DTO,不用的认证和授权规则等,所以如果把所有的业务逻辑都融入到一个应用系统中,就会让系统更难开发、维护和测试,并导致潜在的Bug风险。因此,为每个应用程序创建单独的应用层,并且它们都是用单个领域层来共享核心领域逻辑。为了更加具体的说明,为每种应用程序类型创建不同的.csproj项目:
- 后端管理应用程序 :IssueTracker.Admin.Application和IssueTracker.Admin.Application.Contracts项目
- Web应用程序 :IssueTracker.Public.Application和IssueTracker.Public.Application.Contracts项目
- 移动应用程序 :IssueTracker.Mobile.Application和IssueTracker.Mobile.Application.Contracts项目
二.如何区分领域逻辑和应用逻辑
通常,DDD中的业务逻辑包括领域逻辑和应用逻辑。领域逻辑由系统的核心领域规则组成,而应用程序逻辑实现特定于应用程序的用例。话虽这样说,但是并不容易区分什么是领域逻辑和应用逻辑。
1.在领域服务层中创建组织Organization
下面通过在领域服务中创建Organization这个例子,来尽可能简要说明:
public class OrganizationManager:DomainService
{
private readonly IRepository<Organization> _organizationRepository; //Organization的仓储
private readonly ICurrentUser _currentUser; //当前用户
private readonly IAuthorizationService _authorizationService; //Authorization的服务
private readonly IEmailSender _emailSender; //邮件发送服务
// 公共构造函数,依赖注入
public OrganizationManager(IRepository<Organization> organizationRepository, ICurrentUser currentUser, IAuthorizationService authorizationService, IEmailSender emailSender)
{
_organizationRepository=organizationRepository;
_currentUser=currentUser;
_authorizationService=authorizationService;
_emailSender=emailSender;
}
// 创建一个新的组织
public async Task<Organization> CreateAsync(string name)
{
// 如果组织存在同名,那么抛出异常[正确]
if(await _organizationRepository.AnyAsync(x=>x.Name==name))
{
throw new BusinessException("IssueTracking:DuplicateOrganizationName");
}
// 检查是否拥有创建的权限[错误]
await _authorizationService.CheckAsync("OrganizationCreationPermission");
// 记录⽇志[错误]
Logger.LogDebug($"Creating organization {name} by {_currentUser.UserName}");
// 创建一个新的组织
var organization = new Organization();
// 发送邮件进行提醒[错误]
await _emailSender.SendAsync("[email protected]", "新组织", "新组织名称:"+name);
// 返回一个组织实例
return organization;
}
}- 领域服务不做权限验证,权限验证放在应用层来做
- 用户概念是应用层或展示层的相关概念,记录日志不应该包含当前用户的用户名
- 创建一个新的组织,并发送邮件,这个业务逻辑也应该放在应用层
2.在应用层中使用领域服务创建组织Organization
public class OrganizationAppService:ApplicationService
{
private readonly OrganizationManager _organizationManager; //组织的领域服务
private readonly IPaymentService _paymentService; //支付服务
private readonly IEmailSender _emailSender; //邮件服务
// 公共构造函数,依赖注入
public OrganizaitonAppService(OrganizationManager organizationManager, IPaymentService paymentService, IEmailSender emailSender)
{
_organizationManager=organizationManager;
_paymentService=paymentService;
_emailSender=emailSender;
}
// 创建组织
[UnitOfWork][正确] //工作单元,用于提交事务
[Authorize("OrganizationCreationPermission")][正确]
public async Task<Organization> CreateAsync(CreateOrganizationDto input)
{
// ⽀付组织的费⽤[正确]
await _paymentService.ChargeAsync(CurrentUser.Id, GetOrganizationPrice());
// 通过领域服务,创建一个新的组织实例
var organization = await _organizationManager.CreateAsync(input.Name);
// 保存和更新组织到数据库中[正确]
await _organizationManager.InsertAsync(organization);
// 发送提醒邮件[正确]
await _emailSender.SendAsync("[email protected]", "新组织", "新组织名称:"+name);
//返回实例[错误]
return organization;
}
private double GetOrganizationPrice()
{
return 42;//Gets form somewhere...
}
}应用服务层的输入和输出参数都是DTO,不能返回实体。 至于为什么不将支付放在领域服务中,只能说业务重要也不一定放在领域服务中,详细原因说明参考 [1]。
参考文献:
[1]基于ABP Framework实现领域驱动设计: https://url39.ctfile.com/f/2501739-616007877-f3e258?p=2096 (访问密码: 2096)
边栏推荐
- (ICLR-2022)TADA!用于视频理解的时间自适应卷积
- 指标和标签是做什么的
- Support proxy direct connection to Oracle database, jumpserver fortress v2.24.0 release
- [刷题] 二分答案求解
- If the key is forgotten and multiple devices have different keys, how does the cloud synchronize
- MongoDB stats统计集合占用空间大小
- 时空预测5-GAT
- Tensorflow GPU 1.15 installation
- Difficult performance problems solved in those years -- ext4 defragmentation
- [C language implementation] - dynamic / file / static address book
猜你喜欢

Distributed transaction Seata

ReentrantLock学习之---基础方法

Description of MDM separation of powers and classification and grading authority

AttributeError: ‘Upsample‘ object has no attribute ‘recompute_ scale_ factor‘

To add a composite primary key

(ICLR-2022)TADA!用于视频理解的时间自适应卷积

"Weilai Cup" 2022 Niuke summer multi school training camp 1

LeetCode简单题之数组能形成多少数对

篇7:exited on DESKTOP-DFF5KIK with error code -1073741511.

配置服务器环境
随机推荐
2022搭建企业级数据治理体系
Description of MDM separation of powers and classification and grading authority
指标和标签是做什么的
Cannot find current proxy: Set ‘exposeProxy‘ property on Advised to ‘true‘ to make it available
ReentrantLock学习之---基本属性
Article 7:exited on desktop-dff5kik with error code -1073741511
MySQL主从复制配置详解
Save gas chitoken usage
Covos: no need to decode! Semi supervised Vos acceleration using motion vectors and residuals of compressed video bitstreams (CVPR 2022)
C language - Introduction - syntax - string (11)
Is it safe for CSC qiniu members to open preferential accounts? I don't know if it's the lowest Commission
J2 Redis之 AOF&RDB
深度学习的数学基础
MySQL log introduction
微信小程序插件--wxml-to-canvas(生成图片)
Detailed explanation of MySQL master-slave replication configuration
How to solve the problem that win11 has been switched on after upgrading
Write a starter
Weekend highlights review | establishment of digital RMB industry alliance; China Mobile announced that hefeixin will stop its service
To add a composite primary key