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

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

在本节中,我们将讨论更改 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 实体。

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

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

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

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

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

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

首先,在 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. Web端IM聊天消息该不该用浏览器本地存储?一文即懂!

    本文由转转技术团队刘筱雨分享,原题"一文读懂浏览器本地存储:Web Storage",下文进行了排版和内容优化. 1.引言 鉴于目前浏览器技术的进步(主要是HTML5的普及),在W ...

  2. Xrm.Internal.openDialog打开对话框自定义页面

    在Dynamics CRM平台中使用自定义页面拓展功能实现有多种方式,比如嵌套iframe,比如直接打开一个新页面,再就是打开对话框了,对话框里为自定义页面. 调用方式很简单,先把自定义页面上传好后, ...

  3. linux网桥(Linux Bridge)的一些个人记录

    目录 1. Linux Bridge简述 2. 网桥创建 创建 配置持久化 在Debian/Ubuntu系统上: 在CentOS/RHEL系统上: 启用和验证 3. 关于linux网桥不转发ip帧的问 ...

  4. w3cschool-Nginx 使用手册

    https://www.w3cschool.cn/nginxsysc/ Nginx 使用手册 手册简介 Nginx ("engine x") 是一个高性能的 HTTP 和 反向代理 ...

  5. 第三章 (Nginx+Lua)Redis/SSDB安装与使用

    目前对于互联网公司不使用Redis的很少,Redis不仅仅可以作为key-value缓存,而且提供了丰富的数据结果如set.list.map等,可以实现很多复杂的功能:但是Redis本身主要用作内存缓 ...

  6. win11输入法候选区消失

    使用win11系统时,中文输入按空格可以,但是出现微软官方输入法没有候选区问题. 解决方法: 首先,打开任务管理器 然后,在进程选项中找到windows输入体验进程,结束该进程(该进程会自动重启). ...

  7. 基于MPC的快速transformer安全推理框架

    论文:一种基于安全多方计算的快速Transformer安全推理方案-刘伟欣 摘要 数据隐私泄露问题:当前Transformer推理应用中用户的数据会被泄露给模型提供方 安全推理方法:基于MPC实现Tr ...

  8. RockyLinux9编译安装MySQL8

    Linux版本: Rocky Linux release 9.5 (Blue Onyx) 1.下载 打开MySQL-Community-Server官方下载页面:https://downloads.m ...

  9. delphi中实现http请求和提交

    在对接本地的一个药械监管系统使用实现的代码,编译环境delphi Xe7 ,使用类TIdHTTP实现网络的get请求和post提交 //设置组件的属性 procedure TfrmMain.SetHt ...

  10. UNIDAC中TDataSet组件CachedUpdates属性使用

    官方方法组合示例,使用UpdatesPending属性可判断是否有修改在缓存区中