当前位置: 首页 > news >正文

【微服务实战】01-工程结构概览

文章目录

  • 工程结构概览:定义应用分层及依赖关系
    • 1.应用分层
    • 2.定义Entity
    • 3.仓储层
      • 3.1 工作单元:事务管理
      • 3.2 仓储层
    • 4.领域事件
    • 5.APIController最佳实践

工程结构概览:定义应用分层及依赖关系

1.应用分层

  • 领域模型层
  • 基础设施层 ⇒ 仓储
  • 应用层 ⇒ Api、后台任务Job
  • 共享层

总结

  • 领域模型专注业务的设计,不依赖仓储等基础设施层
  • 基础设施的仓储层仅负责领域模型的取出和存储
  • 使用CQRS模式设计应用层
  • Web Api是面向前端的交互的接口,避免依赖领域模型
  • 将共享代码设计为共享包,使用私有Nuget仓库分发管理

2.定义Entity

要点总结

  • 将领域模型字段的修改设置为私有
  • 使用构造函数表示对象的创建
  • 使用具有业务含义的动作来操作模型字段
  • 领域模型负责对自己数据的处理
  • 领域服务或命令处理者负责调用领域模型业务动作

3.仓储层

3.1 工作单元:事务管理

仓储层最重要的就是事务的管理,这里通过工作单元模式实现事务管理

工作单元特性

  • 使用同一上下文
  • 跟踪实体的状态
  • 保障事务一致性

3.2 仓储层

仓储层接口TEntity必须继承Entity,并且必须实现聚合根,也就是仓储中储存的对象是一个聚合根对象,

public interface IRepository<TEntity>  where TEntity : Entity,IAggregateRoot
{IUnitOfWork UnitOfWork {get;}TEntity Add(TEntity entity);TEntity Update(TEntity entity);
}public interface IRepository<TEntity,TKey>:IRepository<TEntity> where TEntity : Entity<TKey>,IAggregateRoot
{bool Delete(TKey id);TEntity Get(TKey id);
}

4.领域事件

  • 领域事件的构造和添加都应该在领域模型的方法内完成,不应该被外界的代码调用创建,因为这些事件都是领域模型内部发生的
  • 接受领域事件的处理应该定义在应用层
  • 创建完领域模型并保存之后,领域事件的处理程序才触发

总结

1.由领域模型内部创建事件
2.由专有的领域事件处理类处理领域事件
3.根据实际情况来决定是否在同一事务中处理(如一致性、性能等因素)

5.APIController最佳实践

// 伪代码[HttpGet]
public Task<long> CreateOrder([FromBody]CreateOrderViewModel viewModel)
{var model = viewModel.ToModel();// 模型转换return await orderService.CreateOrder(model);// 业务代码调用
}// 服务中代码
class OrderService : IOrderService
{public long CreateOrder(CreateOrderMode model){var address = new Address("测试路","测试市区","123");var order = new Order("订单名称","客户名称",999,address);_orderRepository.Add(order);await _orderRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);return order.Id;}
}

上述代码,随着业务逻辑的复杂化,Controller就会越来越膨胀。而DD领域设计的理念中,更新倾向于把应用程序的每一层明确区分,层与层之间的界限应该是明确的,同时在实现上应该也是隔离的。因此控制器不应该负责处理领域模型,处理仓储这些动作,Controller应该负责与前端交互,主要责任应该是定义输入和输出,实现身份认证、授权等功能。因此上述代码不建议使用

推荐使用中间者模式,演示代码如下

// 这里不建议使用属性服务进行服务注册,因为当使用属性注入的时候,需要把属性设置为public,并且开放set,get方法,可能出现意外情况,这可能导致代码的维护不可控
IMediator _mediator;
public OrderController(IMediator mediator)
{_mediator = mediator;
}// 这里尽可能的定义异步的action,可以帮助提高应用程序的吞吐量
[HttpPost]
public async Task<long> CreateOrder([FromBody] CreateOrderCommans cmd)
{return await _mediator.Send(cmd,HttpContext.RequestAborted);
}

总结

  • 负责用户的输入输出定义
  • 负责身份认证和授权
  • 与领域服务职责区分开,不承载业务逻辑

相关文章:

【微服务实战】01-工程结构概览

文章目录 工程结构概览:定义应用分层及依赖关系1.应用分层2.定义Entity3.仓储层3.1 工作单元&#xff1a;事务管理3.2 仓储层 4.领域事件5.APIController最佳实践 工程结构概览:定义应用分层及依赖关系 1.应用分层 领域模型层基础设施层 ⇒ 仓储应用层 ⇒ Api、后台任务Job共…...

论文导读|European Journal of Operational Research近期文章精选:旅行商问题专题

推文作者&#xff1a;王松阁 编者按 在“European Journal of Operational Research近期论文精选”中&#xff0c;我们有主题、有针对性地选择了European Journal of Operational Research中一些有趣的文章&#xff0c;不仅对文章的内容进行了概括与点评&#xff0c;而且也对文…...

playwright迭代元素

DOM结构 <ul><li>apple</li><li>banana</li><li>orange</li> </ul>迭代元素操作 通过 page.get_by_role("listitem") 会匹配到 apple, banana, orange&#xff0c; 如果要对这一组数据中的每个元素进行操作&#…...

65 | 增长模型案例

增长模型代表了一种综合性的方法论,旨在通过深入了解用户行为、市场趋势和数据洞察,来指导企业制定有效的增长战略。这种方法突破了传统的经验主义,将决策过程建立在数据驱动和实验的基础之上。增长模型不仅仅是一种理论,更是一种实际操作的框架,帮助企业在各个层面实现业…...

Django视图-HttpRequest请求对象和HttpResponse响应对象

文章目录 HttpRequestHttpResponse实践request对象的属性和方法响应 def index(request): 这个request其实就是内部已经封装好的Http请求HttpRequest&#xff0c;它是一个请求对象Django中的视图主要用来接受Web请求&#xff0c;并做出响应。 视图的本质就是一个Python中的函数…...

原来Lambda表达式是这样写的

原来Lambda表达式是这样写的 lambda 是一个匿名函数&#xff0c;我们可以把 lambda 表达式理解为是一段可以传递的代码。 lambda 简明地将代码或方法作为参数传递进去执行。 函数式编程&#xff1a;核心是把函数作为值。 函数式接口 &#xff1a;只有一个抽象方法的接口称之…...

smartsofthelp 5.0 最专业的数据库优化工具,数据库配置优化,数据库高并发优化,SQL 语句优化...

下载地址:百度网盘 请输入提取码 SQL操作返回历史记录&#xff1a; 2023-08-21 20:42:08:220 输入&#xff1a;select version as 版本号 2023-08-21 20:42:08:223 输出&#xff1a;当前数据库实例版本号&#xff1a;Microsoft SQL Server 2012 - 11.0.2100.60 (X64) …...

智影 R100:首款三维Mesh建模的SLAM激光扫描仪

近年来&#xff0c;激光SLAM系统凭借其更加快速且准确获取更丰富信息的优势&#xff0c;迅速风靡测绘领域&#xff0c;让原本耗时耗力的外业测量变得更加高效。手持激光扫描仪作为基于激光SLAM技术衍生的众多产品之一&#xff0c;相较于架站式激光扫描仪更加轻巧便利&#xff0…...

Next.js - Loading UI and Streaming

特殊文件 loading.js 可帮助您使用 React Suspense 创建有意义的加载用户界面。使用此约定&#xff0c;您可以在加载路由段内容时显示来自服务器的即时加载状态。渲染完成后&#xff0c;新的内容会自动切换进来。 即时加载状态 即时加载状态是在导航时立即显示的后备用户界面…...

快速解决Ubuntu 中 wine 程序 中文显示为方块/显示错误/无法显示中文(2023)

解决办法就是在创建prefix的命令行里加上LANG“zh_CN.UTF8” 或 LC_ALL“zh_CN.UTF8”&#xff0c;并安装cjkfonts&#xff0c;即可。 1、生成prefix、安装cjk字体 以下是基本流程&#xff1a; 现在假定wine和winetricks已经装好&#xff0c; // 先创建一个prefix&#xff0…...

漏洞指北-VulFocus靶场专栏-中级02

漏洞指北-VulFocus靶场专栏-中级02 中级005 &#x1f338;thinkphp lang 命令执行&#xff08;thinkphp:6.0.12&#xff09;&#x1f338;step1&#xff1a;burp suite 抓包 修改请求头step2 修改成功&#xff0c;访问shell.php 中级006 &#x1f338;Metabase geojson任意文件…...

【开源三方库】bignumber.js:一个大数数学库

OpenHarmony&#xff08;OpenAtom OpenHarmony简称“OpenHarmony”&#xff09;三方库&#xff0c;是经过验证可在OpenHarmony系统上可重复使用的软件组件&#xff0c;可帮助开发者快速开发OpenHarmony应用。如果是发布到开源社区&#xff0c;称为开源三方库&#xff0c;开发者…...

【C++】iota函数 + sort函数实现基于一个数组的多数组对应下标绑定排序

目录 一、iota函数 1. 函数解析 ​① 迭代器类型(补充) ② 头文件 ③ 参数 2. 函数用途与实例 二、sort函数 1、 函数解读 2、实现倒序排列 2.1 greater 与 less 模板参数 2.2 lambda表达式 三、下标绑定排序&#xff08;zip&#xff09; --- 833.字符串中的查找与替换 一、…...

C# window forms 进度条实现

在 C# Windows Forms 应用程序中&#xff0c;如果在后台执行长时间运行的任务&#xff0c;并希望同时更新进度条&#xff0c;可以使用多线程来实现。这将确保进度条的更新不会阻塞主线程&#xff0c;从而保持界面的响应性。以下是一个示例&#xff0c;演示了如何在后台执行任务…...

ListNode相关

目录 2. 链表相关题目 2.1 合并两个有序链表&#xff08;简单&#xff09;&#xff1a;递归 2.2 删除排序链表中的重复元素&#xff08;简单&#xff09;&#xff1a;一次遍历 2.3 两链表相加&#xff08;中等&#xff09;&#xff1a;递归 2.4 删除链表倒数第N个节点&…...

docker的资源控制及docker数据管理

目录 一.docker的资源控制 1.CPU 资源控制 1.1 资源控制工具 1.2 cgroups有四大功能 1.3 设置CPU使用率上限 1.4 进行CPU压力测试 1.5 设置50%的比例分配CPU使用时间上限 1.6 设置CPU资源占用比&#xff08;设置多个容器时才有效&#xff09; 1.6.1 两个容器测试cpu 2&…...

通过请求头传数据向后端发请求

axios &#xff08;get post请求、头部参数添加&#xff09;傻瓜式入门axios_axiospost请求参数_web_blog的博客-CSDN博客...

产品流程图是什么?怎么做?

产品流程图是什么&#xff1f; 产品流程图是一种图形化的表达方式&#xff0c;用于描述产品开发、制造、销售、使用等各个阶段中涉及的流程、步骤和关系。它通过图形符号、箭头、文本等元素&#xff0c;展示了产品的各个环节之间的关联和顺序&#xff0c;通常被用于可视化产…...

面试之快速学习STL-map

关联式容器 包括 map、multimap、set 以及 multiset 这 4 种容器。和序列式容器区别&#xff1a; a . 关联式容器在存储元素时还会为每个元素在配备一个键&#xff0c;整体以键值对的方式存储到容器中。 b . 相比前者&#xff0c;关联式容器可以通过键值直接找到对应的元素&am…...

ES的索引结构与算法解析

提到ES&#xff0c;大多数爱好者想到的都是搜索引擎&#xff0c;但是明确一点&#xff0c;ES不等同于搜索引擎。不管是谷歌、百度、必应、搜狗为代表的自然语言处理(NLP)、爬虫、网页处理、大数据处理的全文搜索引擎&#xff0c;还是有明确搜索目的的搜索行为&#xff0c;如各大…...

利用ngx_stream_return_module构建简易 TCP/UDP 响应网关

一、模块概述 ngx_stream_return_module 提供了一个极简的指令&#xff1a; return <value>;在收到客户端连接后&#xff0c;立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量&#xff08;如 $time_iso8601、$remote_addr 等&#xff09;&a…...

VB.net复制Ntag213卡写入UID

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

基于matlab策略迭代和值迭代法的动态规划

经典的基于策略迭代和值迭代法的动态规划matlab代码&#xff0c;实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

管理学院权限管理系统开发总结

文章目录 &#x1f393; 管理学院权限管理系统开发总结 - 现代化Web应用实践之路&#x1f4dd; 项目概述&#x1f3d7;️ 技术架构设计后端技术栈前端技术栈 &#x1f4a1; 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 &#x1f5c4;️ 数据库设…...

基于Springboot+Vue的办公管理系统

角色&#xff1a; 管理员、员工 技术&#xff1a; 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能&#xff1a; 该办公管理系统是一个综合性的企业内部管理平台&#xff0c;旨在提升企业运营效率和员工管理水…...

jmeter聚合报告中参数详解

sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample&#xff08;样本数&#xff09; 表示测试中发送的请求数量&#xff0c;即测试执行了多少次请求。 单位&#xff0c;以个或者次数表示。 示例&#xff1a;…...