用例演示 - 更新 / 操作实体

一旦一个实体被创建,它将被用例更新/操作,直到它从系统中删除。可以有不同类型的用例直接或间接地更改实体

在本节中,我们将讨论更改 Issue 的多个属性的典型更新操作。

这次,从更新DTO开始:

public class UpdateIssueDto
{
[Required]
public string Title { get; set; }
public string Text { get; set; }
public Guid? AssignedUserId { get; set; }
}

通过与 IssueCreationDto 比较,您看不到 RepositoryId 。因为,我们的系统不允许跨仓库移动问题(想想GitHub仓库)。只有 Title 是必需的,其他属性是可选的

让我们看看 IssueAppService 中的 Update 实现:

public class IssueAppService : ApplicationService, IIssueAppService
{
//省略了依赖注入 public async Task<IssueDto> UpdateAsync(Guid id, UpdateIssueDto input)
{
//从数据库获取问题实体
var issue = await _issueRepository.GetAsync(id); //修改标题
await _issueManager.ChangeTitleAsync(issue, input.Title); //修改分配人
if(input.AssignedUserId.HasValue)
{
var user = await _userRepository.GetAsync(input.AssignedUserId.Value);
await _issueManager.AssignToAsync(issue, user);
} //修改内容 (没有业务规则,接受任何内容)
issue.Text = input.Text; // 更新实体到数据库
await _issueRepository.UpdateAsync(issue); //返回表示这个新的问题的DTO
return ObjectMapper.Map<Issue, IssueDto>(issue);
}
}
  • UpdateAsync 方法把 id 作为一个单独的参数。它不包含在UpdateIssueDto 中。这是一个设计决策,可以帮助ABP将此服务 自动暴露 为 HTTP API 端点路由。所以,这和DDD无关

  • 首先从数据库中获取 Issue 实体。

  • 使用 IssueManager 的 ChangeTitleAsync ,而不是直接调用 Issue.SetTitle(…) 因为我们需要实现重复的 Title 检查,就像刚才在实体创建中所做的那样。这需要对 Issue 和 IssueManager 类进行一些更改(将在下面解释)。

  • 使用 IssueManager 的 AssignToAsync 方法,如果分配的用户在这个请求中被更改

  • 直接设置 Issue.Text ,因为没有相关的业务规则。如果以后需要,我们总是可以进行重构

  • 将更改保存到数据库。同样,保存实体是协调业务对象和事务的应用程序服务的职责。如果 IssueManager 在 ChangeTitleAsync 和 AssignToAsync 方法内部保存,将会有双数据库操作 参见讨论:为什么问题不在IssueManager中保存到数据库?

  • 最后使用 IObjectMapper 返回一个 IssueDto ,该 IssueDto 是通过映射从更新的 Issue 实体自动创建的

如前所述,我们需要对 Issue 和 IssueManager 类进行一些更改。

首先,在 Issue 类中设置 SetTitle 为 internal:

internal void SetTitle(string title)
{
Title = Check.NotNullOrWhiteSpace(title, nameof(title));
}

然后在 IssueManager 中添加了一个新方法来更改标题:

public async Task ChangeTitleAsync(Issue issue, string title)
{
if(issue.Title == title)
{
return;
} //如果存在相同标题的问题,直接抛错
if(await _issueRepository.AnyAsync(i => i.Title == title))
{
throw new BusinessException("IssueTracking:IssueWithSameTitleExists");
} issue.SetTitle(title);
}

实现领域驱动设计 - 使用ABP框架 - 更新操作实体的更多相关文章

  1. 实现领域驱动设计 - 使用ABP框架 - 什么是领域驱动设计?

    前言: 最近看到ABP官网的一本电子书,感觉写的很好,翻译出来,一起学习下 (Implementing Domain Driven Design) https://abp.io/books DDD简介 ...

  2. 实现领域驱动设计 - 使用ABP框架 - 通用准则

    在进入细节之前,让我们看看一些总体的 DDD 原则 数据库提供者 / ORM 无关性 领域和应用程序层应该与 ORM / 数据库提供程序 无关.它们应该只依赖于 Repository 接口,而 Rep ...

  3. 实现领域驱动设计 - 使用ABP框架 - 存储库

    存储库 Repository 是一个类似于集合的接口,领域层和应用程序层使用它来访问数据持久性系统(数据库),以读写业务对象(通常是聚合) 常见的存储库原则是: 在领域层定义一个存储库接口(因为它被用 ...

  4. 实现领域驱动设计 - 使用ABP框架 - 解决方案概览

    .NET解决方案的分层 下图显示了使用ABP的 应用启动模板 创建的Visual Studio解决方案: 解决方案名称为问题跟踪,它由多个项目组成.通过考虑DDD原则以及开发和部署实践,该解决方案是分 ...

  5. 实现领域驱动设计 - 使用ABP框架 - 创建实体

    用例演示 - 创建实体 本节将演示一些示例用例并讨论可选场景. 创建实体 从实体/聚合根类创建对象是实体生命周期的第一步.聚合/聚合根规则和最佳实践部分建议为Entity类创建一个主构造函数,以保证创 ...

  6. .net core +codefirst(.net core 基础入门,适合这方面的小白阅读) 【我们一起写框架】领域驱动设计的CodeFirst框架(一)—序篇

    .net core +codefirst(.net core 基础入门,适合这方面的小白阅读)   前言 .net core mvc和 .net mvc开发很相似,比如 视图-模型-控制器结构.所以. ...

  7. DDD 领域驱动设计-三个问题思考实体和值对象(续)

    上一篇:DDD 领域驱动设计-三个问题思考实体和值对象 说实话,整理现在这一篇博文的想法,在上一篇发布出来的时候就有了,但到现在才动起笔来,而且写之前又反复读了上一篇博文的内容及评论,然后去收集资料, ...

  8. 【我们一起写框架】领域驱动设计的CodeFirst框架(一)—序篇

    前言 领域驱动设计,其实已经是一个很古老的概念了,但它的复杂度依旧让学习的人头疼不已. 互联网关于领域驱动的文章有很多,每一篇写的都很好,理解领域驱动设计的人都看的懂. 不过,这些文章对于那些初学者而 ...

  9. DDD 领域驱动设计-三个问题思考实体和值对象

    消息场景:用户 A 发送一个消息给用户 B,用户 B 回复一个消息给用户 A... 现有设计:消息设计为实体并为聚合根,发件人.收件人设计为值对象. 三个问题: 实体最重要的特性是什么? Messag ...

  10. (转)EntityFramework之领域驱动设计实践

    EntityFramework之领域驱动设计实践 - 前言 EntityFramework之领域驱动设计实践 (一):从DataTable到EntityObject EntityFramework之领 ...

随机推荐

  1. python SQLAlchemy ORM——从零开始学习03 如何针对数据库信息进行排序

    03 如何进行排序 3-1准备工作: 因为要排序,所以需要随机多谢数据,model见后文.也需要random进行随机 from model import User, Engine from sqlal ...

  2. Redis的高可用?(主从、哨兵、集群)

    高可用有两个含义:一是数据尽量不丢失,二是保证服务尽可能可用. AOF 和 RDB 数据持久化保证了数据尽量不丢失,那么多节点来保证服务尽可能提供服务. 一般在实际生产中,服务不会部署成单节点,主要是 ...

  3. Linux系统安全限制:禁用或限制用户ssh登录(sshd_config、hosts.allow、hosts.deny、nologin、passwd)

    我们知道Linux系统安全性设置有很多方式.常见的有通过firewall防火墙.或者iptables规则实现放行.拦截屏蔽某些特征的网络请求.示例:iptables限制ssh链接服务器     还有一 ...

  4. 二叉树神级遍历算法:morris遍历算法

    morris遍历的实质 建立一种机制,对于没有左子树的节点只到达一次,对于有左子树的节点会到达两次 morris遍历的实现原则 记作当前节点为cur. 如果cur无左孩子,cur向右移动(cur=cu ...

  5. 280:监控和管理LINUX进程

  6. 玩转云端 | 真实模拟,即压即测,天翼云息壤性能测试PTS实践大揭秘!

    满城春色惹人醉,恰是出游好时节. 伴随春暖花开,我国旅游市场快速升温,越来越多的人开始走出家门,去追寻久违的诗和远方.根据文化和旅游部数据中心近日测算,预计2023年,我国国内旅游人数约为45.5亿人 ...

  7. Jenkins插件:Generic Webhook Trigger

    Jenkins插件:Generic Webhook Trigger 作为一名软件测试工程师,在日常工作中,我经常需要使用Jenkins来进行持续集成和持续部署(CI/CD).而Jenkins的众多插件 ...

  8. Linux驱动---LED

    目录 一.pinctrl子系统 二.GPIO子系统 三.GPIO操作步骤 3.1.获取GPIO描述符 3.2.设置方向 3.3.读写值 四.编写LED驱动 4.1.硬件原理图 4.2.修改设备树 4. ...

  9. salesforce零基础学习(一百四十三)零碎知识点小总结(十一)

    本篇参考: https://help.salesforce.com/s/articleView?id=release-notes.rn_lab_dynamic_highlights_panel.htm ...

  10. 甲壳虫ADB助手-让你轻松不用电脑就能卸载电视自带软件

    甲壳虫ADB助手是一款非常使用的安卓ADB调试工具,它适用于各种安卓系统设备,包括手机.平板.手表和电视等等,可以帮助用户直接在手机上对设备进行ADB调试,而且不需要ROOT,支持无线配对连接,让用户 ...