当前位置: 首页 > 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;如各大…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

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

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

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成

厌倦手动写WordPress文章&#xff1f;AI自动生成&#xff0c;效率提升10倍&#xff01; 支持多语言、自动配图、定时发布&#xff0c;让内容创作更轻松&#xff01; AI内容生成 → 不想每天写文章&#xff1f;AI一键生成高质量内容&#xff01;多语言支持 → 跨境电商必备&am…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...

20个超级好用的 CSS 动画库

分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码&#xff0c;而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库&#xff0c;可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画&#xff0c;可以包含在你的网页或应用项目中。 3.An…...