- .NET 指南
- 开始操作
- .NET 教程
- .NET 体系结构组件
- .NET Standard
- 什么是.NET 标准中的新增功能
- 目标框架
- .NET 术语表
- 使用 mdoc 生成文档
- .NET 的体系结构指南
- 使用 ASP.NET Core 和 Azure 构建新式 Web 应用程序
- 现代 Web 应用程序的特征
- 传统 Web 应用程序和单页面应用程序 (Spa) 之间进行选择
- 常见的客户端 Web 技术
- 开发 ASP.NET Core MVC 应用程序
- 使用 ASP.NET Core 应用中的数据
- 测试 ASP.NET Core MVC 应用程序
- Azure 的开发过程
- Azure 托管的 ASP.NET 核心 Web 应用的建议
- 使用 Azure 云和 Windows 容器更新现有 .NET 应用程序 (v1.0)
- 提升和移动现有应用 Azure IaaS
- 将关系数据库迁移到 azure
- 直接迁移现有应用 DevOps
- 到提起并移动现有的.NET 应用到云 DevOps 通用应用程序的原因
- 云 devops 通用应用程序中的 Microsoft 技术
- 云优化应用程序如何呢?
- 如何将现有的.NET 应用程序部署到 Azure App Service
- 将现有的.NET 应用程序部署为 Windows 容器
- 何时不将部署到 Windows 容器
- 何时在你的本地部署 Windows 容器 IaaS VM 基础结构
- 何时将 Windows 容器部署到 Azure Vm (IaaS 云)
- 何时到 Service Fabric 中部署 Windows 容器
- 何时将 Windows 容器部署到 Azure 容器服务 (即,Kubernetes)
- 构建可复原的服务供云: 采用在云中的暂时性故障
- 更新你的应用的监视和遥测
- 更新使用 CI/CD 管道和 DevOps 工具在云中的应用程序的生命周期
- 将迁移到混合云方案
- 演练和技术获取启动的概述
- 技术演练列表
- 技术演练列表
- 结论
- 容器和 Docker 简介
- 什么是 Docker?
- Docker 术语
- Docker 容器、 图像和注册表
- Docker 应用程序生命周期的介绍
- DevOps 协作基础的容器
- 有关适用于容器化应用的 Microsoft 平台和工具的简介
- 使用 Docker 和 Microsoft Azure 设计和开发容器化应用
- Docker 应用程序设计
- 常见容器设计原则
- 整体应用程序
- 状态和 Docker 应用程序中的数据
- SOA 应用程序
- 协调微服务和以高可伸缩性和可用性的 multicontainer 应用程序
- Docker 应用的开发环境
- 对于 Docker 应用程序的内部循环开发工作流
- 使用 Visual Studio Tools for Docker (在 Windows 上的 Visual Studio)
- 使用在 DockerFile 中的 Windows PowerShell 命令来设置 Windows 容器 (Docker 标准基于)
- 使用 Microsoft 工具的 Docker 应用程序 DevOps 工作流
- Docker 应用程序的外部循环 DevOps 工作流中的步骤
- 运行、管理和监视 Docker 生产环境
- 在生产环境中运行由和基于微服务的应用程序
- 管理生产 Docker 环境
- 监视容器化应用程序服务
- 关键结论
- .NET 微服务。 适用于容器化 .NET 应用程序的体系结构
- .NET 微服务。 适用于容器化 .NET 应用程序的体系结构
- 容器和 Docker 简介
- 什么是 Docker?
- Docker 术语
- Docker 容器、 图像和注册表
- 为 Docker 容器选择 .NET Core 还是 .NET Framework
- 一般性指导原则
- 何时选择 Docker 容器中的.NET 核心
- 何时选择 Docker 容器中的.NET Framework
- 决策表:.NET 框架,用于 Docker
- .NET 容器定向到何种操作系统
- 正式.NET Docker 映像
- 构建基于容器和微服务的应用程序
- Containerizing 整体应用程序
- 状态和 Docker 应用程序中的数据
- 面向服务的体系结构
- 微服务体系结构
- 每个微服务构成的数据自主性
- 与物理体系结构的逻辑体系结构
- 分布式的数据管理挑战和解决方案
- 标识每个微服务的域模型边界
- 直接与 API 网关模式的微服务构成客户端通信
- 在微服务体系结构的通信
- 基于消息的异步通信
- 创建、 不断发展,和版本控制 microservice Api 和协定
- 微服务可寻址性和服务注册表
- 创建复合 UI 基于微服务,包括 visual UI 形状和布局由多个微服务生成
- 复原和微服务中的高可用性
- 协调微服务和多容器应用程序的高可伸缩性和可用性
- 使用 Azure Service Fabric
- 基于 Docker 的应用程序的开发流程
- Docker 应用的开发工作流
- 在 Linux 或 Windows Nano Server 主机上部署基于单容器的 .NET Core Web 应用
- 将旧版整体式 .NET Framework 应用程序迁移到 Windows 容器
- 设计和开发基于微服务的多容器 .NET 应用程序
- 设计面向微服务构成的应用程序
- 创建简单的数据驱动 CRUD 微服务
- 定义与 docker-compose.yml 多容器应用程序
- 使用运行的容器的数据库服务器
- 实现基于事件的微服务 (集成事件) 之间的通信
- 实现使用 RabbitMQ 开发或测试环境事件总线
- 订阅事件
- 测试 ASP.NET 核心服务和 web 应用
- 使用 DDD 和 CQRS 模式降低微服务中的业务复杂性
- 应用中的微服务构成的简化的 CQRS 和 DDD 模式
- EShopOnContainers DDD 微服务中的应用 CQRS 和 CQS 方法
- 在 CQRS 微服务中实现读取/查询
- 设计 DDD 面向微服务
- 设计 microservice 域模型
- 实现 microservice 域模型与.NET 核心
- Seedwork (可重用基类,这些类和接口,您的域模型)
- 实现值对象
- 使用枚举类,而不枚举类型
- 设计域模型层中的验证
- 客户端验证 (验证在表示层)
- 域事件: 设计和实现
- 设计基础结构持久性层
- 实现与实体框架核心基础结构持久性层
- 作为持久性基础结构使用 NoSQL 数据库
- 设计微服务应用程序层和 Web API
- 实现微服务应用程序层使用 Web API
- 实现具有恢复能力的应用程序
- 处理部分失败
- 用于处理部分失败的策略
- 实现重试使用指数退让
- 实现弹性 Entity Framework 核心 SQL 连接
- 实现自定义 HTTP 调用的重试使用指数退让
- 使用 Polly 和实施 HTTP 调用重试使用指数退让
- 实现断路器模式
- 运行状况监视
- 保护 .NET 微服务和 Web 应用程序
- 有关在.NET 微服务和 web 应用程序的授权
- 在开发过程中安全地存储应用程序机密
- 使用 Azure 密钥保管库在生产时保护机密
- 记住的要点
- 为服务器应用选择 .NET Core 或 .NET Framework
- 什么是 托管代码 ?
- Automatic Memory Management
- 公共语言运行时 (CLR)
- 语言独立性和与语言无关的组件
- 语言独立性和与语言无关的组件
- 框架库
- .NET Framework 类库概述
- 在 .NET 中使用基类型
- 常规类型系统
- .NET Framework 中的类型转换
- .NET 中的类型转换表
- .NET 中的格式化类型
- 标准数字格式字符串
- 自定义数字格式字符串
- 标准日期和时间格式字符串
- 自定义日期和时间格式字符串
- 标准 TimeSpan 格式字符串
- 自定义的 TimeSpan 格式字符串
- 枚举格式字符串
- 复合格式设置
- 执行格式设置操作
- 如何:用前导零填充数字
- 如何:从特定日期中提取星期几
- 如何:定义和使用自定义数值格式提供程序
- 如何:往返日期和时间值
- 如何:将用户在 Web 控件中输入的数值转换为数字
- 如何:向 Web 用户显示本地化的日期和时间信息
- 如何:显示日期和时间值中的毫秒
- 如何:用非公历日历显示日期
- 操作在.NET 中的字符串
- 在.NET 中使用字符串的最佳做法
- .NET 中的基本字符串操作
- 在.NET 中创建新的字符串
- 剪裁和移除从.NET 中的字符串的字符
- .NET 中的空白字符串
- 比较.NET 中的字符串
- 更改.NET 中的大小写
- 在.NET 中使用 StringBuilder 类
- 如何: 在.NET 中执行基本字符串操作
- .NET 正则表达式
- 正则表达式语言 - 快速参考
- 正则表达式中的字符转义
- 正则表达式中的字符类
- 正则表达式中的定位点
- 正则表达式中的分组构造
- 正则表达式中的限定符
- 正则表达式中的反向引用构造
- 正则表达式中的备用构造
- 正则表达式中的替代
- 正则表达式选项
- 正则表达式中的其他构造
- .NET 中的正则表达式的最佳实践
- 正则表达式对象模型
- 正则表达式行为的详细信息
- 正则表达式中的回溯
- 正则表达式中的编译和重复使用
- 正则表达式中的线程安全
- 正则表达式示例
- 正则表达式示例:扫描 HREF
- 正则表达式示例:更改日期格式
- 如何:从 URL 中提取协议和端口号
- 如何:从字符串中剥离无效字符
- 如何:确认字符串是有效的电子邮件格式
- 在.NET 中编码的字符
- 在.NET 中分析字符串
- NET 中分析数值字符串
- 分析日期和时间字符串.NET 中
- .NET 中分析其他字符串
- .NET 类库
- .NET 可移植性分析器
- 在 .NET 中处理和引发异常
- .NET 程序集文件格式
- 内存管理和.NET 中的垃圾回收
- 垃圾回收
- 垃圾回收的基础
- 垃圾回收和性能
- 被动回收
- 滞后时间模式
- 针对共享 Web 承载优化
- 垃圾回收通知
- 应用程序域资源监控
- 弱引用
- 泛型类型(泛型)概述
- 委托和 lambda
- LINQ(语言集成查询)
- 常规类型系统和公共语言规范
- 异步概述
- 深入了解异步
- 异步编程模式
- 基于任务的异步模式 (TAP)
- 实现基于任务的异步模式
- 使用基于任务的异步模式
- 与其他异步模式和类型互操作
- 基于事件的异步模式 (EAP)
- 使用基于事件的异步模式进行多线程编程
- 基于事件的异步模式概述
- 实现基于事件的异步模式
- 实现基于事件的异步模式的最佳做法
- 确定何时实现基于事件的异步模式
- 演练:实现支持基于事件的异步模式的组件
- 演练:实现支持基于事件的异步模式的组件
- 如何:实现基于事件的异步模式的客户端
- 如何:使用支持基于事件的异步模式的组件
- 异步编程模型 (APM)
- 使用 IAsyncResult 调用异步方法
- 使用 AsyncWaitHandle 阻止应用程序的执行
- 通过结束异步操作来阻止应用程序执行
- 轮询异步操作的状态
- 使用 AsyncCallback 委托结束异步操作
- 使用 AsyncCallback 委托和状态对象
- 使用委托进行异步编程
- 使用异步方式调用同步方法
- 本机互操作性
- 集合和数据结构
- .NET Framework 中的数字
- 日期、时间和时区
- 时区概述
- 在 DateTime、DateTimeOffset、TimeSpan 和 TimeZoneInfo 之间进行选择
- 查找本地系统上定义的时区
- 如何: 枚举计算机上存在的时区
- 如何: 访问预定义的 UTC 和当地时间区域对象
- 如何: 实例化 TimeZoneInfo 对象
- 实例化 DateTimeOffset 对象
- 如何: 创建不带调整规则的时区
- 如何: 创建带有调整规则的时区
- 保存和还原时区
- 如何: 将时区保存到嵌入的资源
- 如何: 从嵌入的资源还原时区
- 使用日历
- 使用日期和时间执行算术运算
- 如何: 在日期和时间运算中使用时区
- 在 DateTime 与 DateTimeOffset 之间进行转换
- 在各时区之间转换时间
- 如何: 解决不明确的时间
- 如何: 让用户解决不明确的时间
- 处理和引发事件
- 如何:引发和使用事件
- 如何:使用事件属性处理多个事件
- 如何:在 Web 窗体应用程序中使用事件
- 观察程序设计模式
- 观察程序设计模式最佳做法
- 如何:实现提供程序
- 如何:实现观察程序
- 托管执行过程
- 元数据和自描述组件
- 在 .NET Framework 中构建控制台应用程序
- .NET Framework 中的并行处理和并发
- .NET Framework 应用程序要点
- 文件和流 I/O
- 对 .NET Framework 应用程序进行全球化和本地化
- 全球化
- 本地化评审
- 本地化
- 不区分区域性的字符串操作
- 执行不区分区域性的字符串操作
- 执行不区分区域性的字符串比较
- 执行不区分区域性的大小写更改
- 在集合中执行不区分区域性的字符串操作
- 在数组中执行不区分区域性的字符串操作
- 开发全球通用应用程序的最佳做法
- 利用特性扩展元数据
- 应用特性
- 编写自定义特性
- 检索存储在特性中的信息
- 框架设计准则
- 命名准则
- 大小写约定
- 通用命名约定
- 程序集和 DLL 的名称
- 命名空间的名称
- 类、结构和接口的名称
- 类型成员的名称
- 命名参数
- 命名资源
- 类型设计准则
- 在类和结构之间选择
- 抽象类设计
- 静态类设计
- 接口设计
- 结构设计
- 枚举设计
- 嵌套类型
- 成员设计准则
- 成员重载
- 属性设计
- 构造函数设计
- 事件设计
- 字段设计
- 扩展方法
- 运算符重载
- 参数设计
- 扩展性设计
- 未密封类
- 受保护的成员
- 事件和回调
- 虚成员
- 抽象(抽象类型和接口)
- 用于实现抽象的基类
- 密封
- 异常设计准则
- 异常引发
- 使用标准异常类型
- 异常和性能
- 使用准则
- 数组
- 特性
- 集合准则
- 序列化
- System.Xml 使用情况
- 相等运算符
- 常见设计模式
- 依赖项属性
- 释放模式
- XML 文档和数据
- XML 处理选项
- 内存中 XML 数据处理
- 使用 DOM 模型处理 XML 数据
- XML 文档对象模型 (DOM)
- XML 节点类型
- XML 文档对象模型 (DOM) 层次结构
- 将对象层次结构映射到 XML 数据
- 创建 XML 文档
- 将 XML 文档读入 DOM
- 嵌入到文档中的样式表指令
- 从读取器中加载数据
- 加载 DOM 时的空白和有效空白处理
- 访问 DOM 中的属性
- 将实体声明和实体引用读入 DOM
- 保留实体引用
- 扩展但不保留实体引用
- 将节点插入 XML 文档中
- 在 DOM 中创建新节点
- 为 DOM 中的元素创建新属性
- 创建新节点时的 XML 元素和属性名验证
- 创建新实体引用
- 命名空间对包含元素和属性的新节点的实体引用扩展的影响
- 复制现有节点
- 将现有节点从一个文档复制到另一个文档
- 复制文档片段
- 移除 XML 文档中的节点、内容和值
- 从 DOM 中移除节点
- 移除 DOM 中元素节点的属性
- 移除 DOM 中的节点内容
- 修改 XML 文档中的节点、内容和值
- 在 DOM 中验证 XML 文档
- 保存和写出文档
- 使用 XPath 导航选择节点
- 解析外部资源
- 使用 XmlNameTable 的对象比较
- NamedNodeMap 和 NodeList 中的节点集合
- 按名称或索引检索未排序节点
- 按索引检索已排序节点
- NodeList 和 NamedNodeMap 的动态更新
- DOM 中的命名空间支持
- DOM 中的命名空间和 DTD
- 更改 XML 文档中的命名空间声明
- 更改命名空间前缀属性
- 使用 mlNodeChangedEventArgs 的 XML 文档中的事件处理
- 扩展 DOM
- 使用 XPath 数据模型处理 XML 数据
- 使用 XPathDocument 和 XmlDocument 读取 XML 数据
- 使用 XPathNavigator 选择、计算和匹配 XML 数据
- 使用 XPathNavigator 选择 XML 数据
- 使用 XPathNavigator 计算 XPath 表达式
- 使用 XPathNavigator 匹配节点
- XPath 查询识别的节点类型
- XPath 查询和命名空间
- 已编译的 XPath 表达式
- XPath 命名空间浏览
- 使用 XPathNavigator 访问 XML 数据
- 使用 XPathNavigator 的节点集定位
- 使用 XPathNavigator 的属性和命名空间节点定位
- 使用 XPathNavigator 提取 XML 数据
- 使用 XPathNavigator 访问强类型 XML 数据
- 用户定义的函数和变量
- 使用 XPathNavigator 编辑 XML 数据
- 使用 XPathNavigator 插入 XML 数据
- 使用 XPathNavigator 修改 XML 数据
- 使用 XPathNavigator 移除 XML 数据
- 使用 XPathNavigator 验证架构
- 使用 LINQ to XML 处理 XML 数据
- XSLT 转换
- 使用 XslCompiledTransform 类
- XslCompiledTransform 类的输入
- XslCompiledTransform 类的输出选项
- 在 XSLT 处理期间解析外部资源
- 扩展 XSLT 样式表
- XSLT 扩展对象
- XSLT 参数
- 使用 msxsl:script 的脚本块
- 可恢复的 XSLT 错误
- 如何:转换节点片断
- 从 XslTransform 类迁移
- 如何:迁移 XslTransform 代码
- XSLT 安全注意事项
- XSLT 编译器 (xsltc.exe)
- 如何:通过使用程序集执行 XSLT 转换
- XslTransform 类的 XSLT 转换
- XslTransform 类中任意行为的实现
- XslTransform 类实现 XSLT 处理器
- XslTransform 的输出
- 不同存储区的 XSLT 转换
- 解析外部 XSLT 样式表和文档
- 样式表参数和扩展对象的 XsltArgumentList
- XSLT 样式表脚本使用<msxsl: script>
- 对 msxsl:node-set() 函数的支持
- 转换中的节点集
- 转换中的结果树片断
- 转换中的 XPathNavigator
- 转换中的 XPathNodeIterator
- XslTransform 的 XPathDocument 输入
- XslTransform 的 XmlDataDocument 输入
- XslTransform 的 XmlDocument 输入
- 使用 XML 架构
- XML 架构对象模型 (SOM)
- XML 架构对象模型概述
- 读写 XML 架构
- 生成 XML 架构
- 遍历 XML 架构
- 编辑 XML 架构
- 包含或导入 XML 架构
- 用于编译架构的 XmlSchemaSet
- 后架构编译信息集
- 使用 XmlSchemaSet 进行 XML 架构 (XSD) 验证
- XmlSchemaCollection 架构编译
- 使用 XmlSchemaCollection 进行 XDR 验证
- 使用 XmlSchemaCollection 进行 XML 架构 (XSD) 验证
- XmlSchemaValidator 基于推送的验证
- 推断 XML 架构
- 从 XML 文档推断架构
- 推断架构节点类型和结构的规则
- 推断简单类型的规则
- 关系数据和 ADO.NET 的 XML 集成
- 管理 XML 文档中的命名空间
- System.Xml 类中的类型支持
- 将 XML 数据类型映射到 CLR 类型
- XML 类型支持实现说明
- XML 数据类型的转换
- 将字符串转换为 .NET Framework 数据类型
- 将 .NET Framework 类型转换为字符串
- 托管线程处理
- 托管线程处理基本知识
- 线程与线程处理
- 托管线程中的异常
- 为多线程处理同步数据
- 托管线程状态
- 前台和后台线程
- Windows 中的托管和非托管线程处理
- Thread.Suspend、垃圾回收和安全点
- 线程本地存储区:线程相关的静态字段和数据槽
- 托管线程中的取消
- 如何:通过轮询侦听取消请求
- 如何:注册取消请求的回调
- 如何:侦听具有等待句柄的取消请求
- 如何:侦听多个取消请求
- 使用线程和线程处理
- 启动时创建线程并传递数据
- 暂停和继续线程
- 销毁线程
- 调度线程
- 以协作方式取消线程
- 托管线程处理的最佳做法
- 线程处理对象和功能
- 托管线程池
- 计时器
- EventWaitHandle、AutoResetEvent、CountdownEvent、ManualResetEvent
- EventWaitHandle
- AutoResetEvent
- ManualResetEvent 和 ManualResetEventSlim
- CountdownEvent
- Mutexes
- 互锁操作
- 读取器/编写器锁
- Semaphore 和 SemaphoreSlim
- 同步基元概述
- 屏障 (.NET Framework)
- 如何:使用屏障来使并发操作保持同步
- SpinLock
- 如何:使用 SpinLock 进行低级别同步
- 如何:在 SpinLock 中启用线程跟踪模式
- SpinWait
- 如何:使用 SpinWait 实现两阶段等待操作
- .NET 中的并行编程
- 任务并行库 (TPL)
- 数据并行(任务并行库)
- 如何:编写简单的 Parallel.For 循环
- 如何:编写简单的 Parallel.ForEach 循环
- 如何:编写具有线程局部变量的 Parallel.For 循环
- 如何:编写具有线程局部变量的 Parallel.ForEach 循环
- 如何:取消 Parallel.For 或 ForEach Loop
- 如何:处理并行循环中的异常
- 如何:加快小型循环体的速度
- 如何:使用并行类循环访问文件目录
- 基于任务的异步编程
- 使用延续任务来链接任务
- 已附加和已分离的子任务
- 任务取消
- 异常处理(任务并行库)
- 如何:使用 Parallel.Invoke 来执行并行操作
- 如何:从任务中返回值
- 如何:取消任务及其子级
- 如何:创建预先计算的任务
- 如何:使用并行任务遍历二叉树
- 如何:解除嵌套任务的包装
- 如何:防止子任务附加到其父任务
- 数据流(任务并行库)
- 如何:将消息写入数据流块和从数据流块读取消息
- 如何:实现制造者-使用者数据流模式
- 如何:在数据流块收到数据时执行操作
- 演练:创建数据流管道
- 如何:取消链接数据流块
- 演练:在 Windows 窗体应用程序中使用数据流
- 如何:取消数据流块
- 演练:创建自定义数据流块类型
- 如何:使用 JoinBlock 从多个源读取数据
- 如何:指定数据流块中的并行度
- 如何:在数据流块中指定任务计划程序
- 演练:使用 BatchBlock 和 BatchedJoinBlock 提高效率
- 将 TPL 用于其他异步模式
- TPL 和传统 .NET Framework 异步编程
- 如何:在任务中包装 EAP 模式
- 数据并行和任务并行中的潜在缺陷
- 并行 LINQ (PLINQ)
- PLINQ 介绍
- 了解 PLINQ 中的加速
- PLINQ 中的顺序保留
- PLINQ 中的合并选项
- PLINQ 的潜在缺陷
- 如何:创建并执行简单的 PLINQ 查询
- 如何:在 PLINQ 查询中控制排序
- 如何:合并并行和顺序 LINQ 查询
- 如何:处理 PLINQ 查询中的异常
- 如何:取消 PLINQ 查询
- 如何:编写自定义 PLINQ 聚合函数
- 如何:在 PLINQ 中指定执行模式
- 如何:在 PLINQ 中指定合并选项
- 如何:使用 PLINQ 循环访问文件目录
- 如何:衡量 PLINQ 查询性能
- PLINQ 数据示例
- 用于并行编程的数据结构
- 并行诊断工具
- PLINQ 和 TPL 的自定义分区程序
- 如何:实现动态分区
- 如何:实现静态分区的分区程序
- PLINQ 和 TPL 中的 Lambda 表达式
- 其他阅读材料(并行编程)
- .NET Framework 中的安全性
- 安全性的基础概念
- 基于角色的安全性
- 主体和标识对象
- 如何:创建 WindowsPrincipal 对象
- 如何:创建 GenericPrincipal 和 GenericIdentity 对象
- 替换 Principal 对象
- 模拟与恢复
- .NET Framework 加密模型
- 加密服务
- 生成加密和解密的密钥
- 如何:将非对称密钥存储在密钥容器中
- 加密数据
- 解密数据
- 加密签名
- 使用哈希代码确保数据完整性
- 创建加密方案
- 如何:用对称密钥对 XML 元素进行加密
- 如何:用对称密钥对 XML 元素进行解密
- 如何:用非对称密钥对 XML 元素进行加密
- 如何:用非对称密钥对 XML 元素进行解密
- 如何:用 X.509 证书对 XML 元素进行加密
- 如何:用 X.509 证书对 XML 元素进行解密
- 如何:使用数字签名为 XML 文档签名
- 如何:验证 XML 文档的数字签名
- 如何:使用数据保护
- 如何:访问硬件加密设备
- 演练:创建加密应用程序
- 代码安全维护指南
- 保护状态数据
- 安全性和用户输入
- 安全和争用条件
- 安全性和进行中的代码生成
- .NET 中的序列化
- 序列化帮助主题
- 二进制序列化
- 序列化概念
- 基本序列化
- 有选择的序列化
- 自定义序列化
- 序列化过程中的步骤
- 版本容错序列化
- 序列化准则
- 如何:对序列化数据进行分块
- 如何: 确定是否可序列化的标准.NET 对象
- 请参阅
- 请参阅
- XML 和 SOAP 序列化
- 如何:控制派生类的序列化
- XML 序列化简介
- 如何:反序列化对象
- XML 序列化示例
- XML 架构定义工具和 XML 序列化
- How to: Use the XML Schema Definition Tool to Generate Classes and XML Schema Documents
- 使用属性控制 XML 序列化
- 用来控制 XML 序列化的属性
- 如何:指定 XML 流的替代元素名称
- 如何:序列化对象
- 如何:限定 XML 元素和 XML 属性名
- 使用 XML Web services 进行 XML 序列化
- 如何:将对象序列化为 SOAP 编码的 XML 流
- 如何:重写编码的 SOAP XML 序列化
- 用来控制编码的 SOAP 序列化的属性
- <system.xml.serialization> 元素
- <dateTimeSerialization> 元素
- <schemaImporterExtensions> 元素
- <xmlSerializer> 元素
- 序列化工具
- XML 序列化程序生成器工具 (Sgen.exe)
- XML Schema Definition Tool (Xsd.exe)
- .NET Framework 的序列化示例
- 基本序列化技术示例
- 使用 XmlSerializer 自定义序列化顺序
- SchemaImporterExtension 技术示例
- 版本容错序列化技术示例
- Web 服务泛型序列化技术示例
- Web 服务 IXmlSerializable 技术示例
- 使用 .NET Framework 针对多个平台开发
- 使用可移植类库的跨平台开发
- 将可移植类库与模型-视图-视图模型配合使用
- 面向多个平台的库的应用程序资源
- .NET Framework 对 Windows 应用商店应用程序和 Windows 运行时的支持情况
- 向 Windows 运行时传递 URI
- WindowsRuntimeStreamExtensions.AsRandomAccessStream(System.IO.Stream) 方法
设计面向微服务构成的应用程序
本部分重点介绍开发假设服务器端企业应用程序。
应用程序规范
假设应用程序执行业务逻辑、 访问数据库,并返回 HTML、 JSON 或 XML 响应处理请求。 我们将假定该应用程序必须支持各种客户端,包括桌面浏览器运行单页面应用程序 (Spa)、 传统 web 应用程序、 移动 web 应用和本机移动应用。 应用程序还可能会公开一个 API,使第三方使用。 它还应该能够以异步方式将其微服务或外部应用程序的集成,以便的方法将帮助的微服务对于部分故障的复原能力。
应用程序将这些类型的组件包括:
- 表示组件。 这些是负责处理用户界面和使用远程服务。
- 域或业务逻辑。 这是应用程序的域的逻辑。
- 数据库访问逻辑。 这包括数据访问组件负责访问数据库 (SQL 或 NoSQL)。
- 应用程序集成逻辑。 这包括主要基于消息代理的消息传递通道。
应用程序需要高可伸缩性,同时允许其垂直的子系统来自主,向外扩展,因为某些子系统需要比其他的多个可伸缩性。
应用程序必须能够在多个基础结构环境 (多个公共云基础架构并在本地) 部署,理想情况下应该可以跨平台,可以轻松地将从 Linux 为 Windows (反之亦然)。
开发团队上下文
我们还假设以下关于应用程序的开发过程:
- 必须将重点放在应用程序的不同业务区域上的多个开发团队。
- 新的团队成员必须提高工作效率快速,以及应用程序必须易于理解和修改。
- 应用程序将具有的长期发展和不断变化的业务规则。
- 你需要良好的长期可维护性意味着具有灵活性,同时能够使用在其他子系统上的最小影响更新多个子系统实现将来新更改时。
- 你想做法持续集成和连续部署的应用程序。
- 你想要利用新兴技术 (框架,编程语言,等等) 时不断演变的应用程序。 您不想要使应用程序的完整迁移,在迁移到新的技术,因为这将导致高成本,并影响的可预测性和应用程序的稳定性。
选择一种体系结构
应用程序部署体系结构应该是什么? 对于应用程序,以及开发上下文中,规范强烈建议你应通过将其分解到自治子系统中的协作微服务和容器,窗体,其中 microservice 设计应用程序是一个容器。
在此方法中,每个服务 (容器) 实现一组提供一致性和较窄相关的函数。 例如,应用程序可能包含目录服务,服务、 购物篮服务、 用户配置文件服务、 等排序等服务。
微服务通信使用协议如 HTTP (REST),但也以异步方式 (即 AMQP) 只要有可能,尤其是当传播使用更新集成事件。
开发和部署为独立于另一个容器微服务时。 这意味着,可以开发和部署某些 microservice 而不会影响其他子系统,开发团队。
每个微服务都有自己的数据库,使其能够从其他微服务完全分离。 如有必要,从不同的微服务的数据库之间的一致性被实现使用 (通过逻辑事件 bus) 的应用程序级集成事件的处理命令和查询责任分离 (CQRS) 中。 正因如此,业务约束必须接受多个微服务之间的最终一致性和相关数据库。
eShopOnContainers: 用于.NET 核心和微服务部署使用容器的引用应用程序
以便你可以专注于体系结构和技术而不是你可能不知道 hypothetic 业务领域的考虑,我们已选择的已知的业务域 — 即的简化的电子商务 (e-式应用商店) 应用程序提供的目录产品,接受来自客户的订单,验证清单,并执行其他业务功能。 此容器基于应用程序的源代码位于 eShopOnContainers GitHub 存储库。
该应用程序包含多个子系统,包括多个应用商店 UI 前端 (Web 应用程序和本机移动应用程序),以及后端微服务和容器的所有所需的服务器端操作。 图 8-1 显示引用应用程序的体系结构。
图 8-1 。 EShopOnContainers 引用演示直接的微服务构成客户端通信和事件 bus 的应用程序
宿主环境 。 在图 8-1,你会看到一个 Docker 主机中部署的多个容器。 部署到使用 docker 一台 Docker 主机时,会出现此情况的编写命令。 但是,如果你是使用 orchestrator 或容器群集时,每个容器无法在另一台主机 (节点) 中运行,并且任何节点无法运行任意数量的容器,如我们前面所述体系结构节中。
通信体系结构 。 EShopOnContainers 应用程序使用两个通信类型,具体取决于功能的操作 (而不是更新和事务的查询) 的类型:
- 直接微服务构成客户端通信。 接受更新或从客户端应用程序的事务处理命令时,这用于查询和。
- 基于事件的异步通信。 通过在微服务之间传播更新,或与外部应用程序集成事件总线发生这种情况。 可以使用任何如 RabbitMQ,或使用 Azure Service Bus、 NServiceBus、 MassTransit 或 Brighter 等的更高级别的服务总线的消息传递代理基础结构技术实现的事件总线。
作为一套微服务容器的形式部署应用程序。 客户端应用程序可以与这些容器通信以及微服务之间进行通信。 如前文所述,此初始体系结构使用直接微服务构成客户端通信体系结构,这意味着,直接客户端应用程序可以发出请求到每个微服务。 每个微服务具有类似 https://servicename.applicationname.companyname 公共终结点。 如果需要,每个微服务可以使用其他 TCP 端口。 在生产中,URL 将映射到微服务的负载平衡器,其中将请求分布到可用的微服务实例。
API 网关 vs 的重要说明。在 eShopOnContainers 的直接通信。 如本指南的体系结构部分中所述,直接微服务构成客户端通信体系结构可以在生成的大型复杂基于微服务构成的应用程序有缺点。 但它可以对已经足够好一个小的应用程序,如 eShopOnContainers 中启动应用程序,其目标是要专注于更简单的获取的 Docker 容器基于应用程序,并且我们不想创建可以影响单个整体 API 网关微服务的开发自治。
但是,如果你要设计大型基于微服务构成的应用程序的微服务数十个,我们强烈建议你考虑 API 网关模式,如我们的体系结构部分中所述。 无法重构此体系结构决策后立即可供生产应用程序和专门进行外观考虑为远程客户端。 具有多个的自定义 API 网关具体取决于客户端应用程序的外观可以提供有关每个客户端应用程序的不同的数据聚合的好处以及可以向客户端应用隐藏内部微服务或 Api 和单个该层中授权。
但是,并且提到过,请注意针对大型和整体 API 网关,可能会终止微服务的开发自治。
每个微服务构成的数据自主性
在示例应用程序,每个微服务拥有其自己的数据库或数据源,并且每个数据库或数据源部署为另一个容器。 这种设计决策进行仅以方便开发人员可以从 GitHub 获取代码、 克隆它,并在 Visual Studio 或 Visual Studio Code 中打开它。 或,或者,它可以轻松地编译自定义的 Docker 映像使用.NET 核心 CLI 和 Docker CLI 中,然后部署和在 Docker 开发环境中运行。 两种方式的容器用于数据源的允许开发人员生成和部署在几分钟内,而无需设置外部数据库或任何其他数据源具有对基础结构 (云中或本地) 的硬依赖项。
在实际生产环境中,高可用性和可伸缩性,数据库应基于数据库服务器中的云或本地,但不是在容器。
因此,部署微服务 (和即使对于此应用程序中的数据库) 的单位为 Docker 容器,并且引用应用程序是一个多容器应用程序,可满足微服务原则。
其他资源
- eShopOnContainers GitHub 存储库。源引用应用程序的代码 https://aka.ms/eShopOnContainers/
一个基于微服务构成的解决方案的优点
像这样一个基于 microservice 解决方案带来诸多好处:
每个微服务是相对较小-易于管理和发展 。 尤其是在下列情况下:
- 很容易开发人员了解并快速开始使用良好的工作效率。
- 这使得开发人员提高工作效率,快速、 启动容器。
- IDE 类似于 Visual Studio 可以负载较小项目快,使开发人员工作效率。
- 每个微服务可以设计、 开发和部署独立于其他的微服务,提供灵活性,因为它是更轻松地频繁部署微服务的新版本。
可以横向扩展应用程序的各个区域 。 例如,目录服务或购物篮服务可能需要向外扩展,但不是排序的过程。 微服务基础结构将更高效减少比整体体系结构,向外缩放时使用的资源。
你可以将多个团队的开发工作划分 。 每个服务可以拥有的是单个开发团队。 每个团队可以管理、 开发、 部署和缩放其服务独立于团队的其余部分。
问题是更好隔离 。 如果一个服务时出现问题,只有该服务最初影响 (除非错误设计使用时,直接之间的相关性微服务),和其他服务可以继续处理请求。 相比之下,整体部署体系结构中的一个异常的组件可以关闭整个系统中,尤其是当涉及资源,例如内存泄漏。 此外时微服务中的问题得以解决后,, 可以部署仅受影响的微服务,而不会影响应用程序的其余部分。
你可以使用最新技术 。 因为你可以开始独立开发服务,然后运行它们并排 (得益于容器和.NET Core),你可以开始而不停滞在较旧的堆栈或框架,用于整个迅速地使用的最新技术和框架应用程序。
一个基于微服务构成的解决方案的不足之处
像这样一个基于 microservice 解决方案还存在一些缺点:
分布式应用程序 。 分发应用程序的开发人员增加复杂性,当设计和构建这些服务。 例如,开发人员必须实现 interservice 通信使用协议,如 HTTP 或 AMPQ,增加了用于测试和异常处理的复杂性。 它还添加到系统的延迟。
部署的复杂性 。 拥有数十微服务类型,并需要高可伸缩性 (它需要能够创建每个服务的多个实例和这些服务分摊到多个主机) 的应用程序的方法来 IT 运营和管理部署的复杂性度很高。 如果你不使用面向微服务的基础结构 (如 orchestrator 和计划程序),其他的复杂性可能需要比业务应用程序本身的更多的开发工作。
原子事务 。 通常多个微服务之间的原子事务中不可能。 业务要求需要采用多个微服务之间的最终一致性。
增加全局资源需求 (总内存、 驱动器和网络资源的所有服务器或主机)。 在许多情况下,使用微服务方法时,将整体应用程序时所需的基于微服务构成的新应用程序的全局资源量将大于原始的整体应用程序的基础结构需求。 这是因为更高程度的粒度和分布式的服务需要更具有全局性占用的资源。 资源的增加的使用给定低成本的常规和一个优势是能够扩大相比长期成本时不断演变的整体应用程序的应用程序只是某些区域中的资源,但是,是通常为一个很好权衡大,长期的应用程序。
直接 client‑to‑microservice 通信问题 。 大型,使用数十个微服务应用程序时,有挑战和限制如果应用程序要求直接微服务构成客户端通信。 一个问题是客户端的需求和每个微服务公开的 Api 的潜在不匹配。 在某些情况下,客户端应用程序可能需要进行许多单独的请求,以构成的用户界面,这会通过 Internet 效率低下,并将对移动网络不切实际。 因此,客户端应用程序中对后端系统的请求应将最小化。
与直接微服务构成客户端通信的另一个问题是某些微服务可能正在使用不是 Web 友好的协议。 一个服务可能使用的二进制协议,而另一个服务可能使用 AMQP 消息。 这些协议不是 firewall‑friendly,最好在内部使用。 通常情况下,应用程序应使用在防火墙外的通信协议,如 HTTP 和 Websocket。
尚未使用此直接 client‑to‑service 方法的另一个缺点是,它使得难以重构这些微服务的协定。 随着时间的推移开发人员可能想要更改系统分区到服务的方式。 例如,它们可能会合并两个服务或拆分为两个或多个服务的服务。 但是,如果客户端直接与服务进行通信,则执行这种重构可以中断与客户端应用程序兼容性。
中所述的体系结构部分,在设计和构建复杂的应用程序基于微服务时,你可以考虑使用多个的细化 API 网关而不是更简单的直接 client‑to‑microservice 通信方法。
分区微服务 。 最后,无论微服务体系结构采用哪种方法,另一个难题确定如何分区到多个微服务端到端应用程序。 如本指南的体系结构部分中所述,有几种技术和您可以采取的方法。 基本上,你需要识别的区域的应用程序从其他区域分隔和具有硬依赖项的数量较少。 在许多情况下,这是用例通过到服务分区对齐的。 例如,在我们电子商店的应用程序,我们具有一排序的服务,它负责与订单过程相关的所有业务逻辑。 我们还提供目录服务和购物篮服务实现其他功能。 理想情况下,每个服务应具有仅职责一小部分。 这是类似于单独责任原则 (SRP) 应用于类,以指出,一个类只能有一个确实需要更改。 但在这种情况下,它是有关微服务,因此该作用域将是大于单个类。 最重要的是,微服务必须是完全自治、 端到端,包括负责其自己的数据源。
与内部体系结构和设计模式的外部
外部体系结构是由多个服务,按照本指南的体系结构部分所述的原则的微服务体系结构。 但是,根据每个微服务,并独立于你选择的高级微服务体系结构的性质,它很常见,并且有时最好具有不同的内部体系结构,每种为基于不同的模式,不同微服务。 微服务甚至可以使用不同的技术和编程语言。 图 8-2 演示了这种多样性。
图 8-2 。 外部与内部体系结构和设计
例如,在我们eShopOnContainers示例中,目录、 购物篮和用户配置文件微服务是简单 (基本上,CRUD 子系统)。 因此,其内部体系结构和设计非常简单。 但是,你可能必须其他微服务,如排序 microservice,这是更复杂,并且与域复杂性度很高表示不断变化的业务规则。 在类似这样的情况下,你可能想要实现更高级的模式中特定的微服务,通过域驱动设计 (DDD) 方法定义为我们在中做的一样eShopOnContainers排序微服务。 (我们将查看更高版本的实现进行说明这部分中的这些 DDD 模式eShopOnContainers排序微服务。)
对于每个微服务使用的不同技术的另一个原因可能是每个微服务的性质。 例如,它可能是更好的做法使用功能的编程语言,如 F#,或者如果你正面向 AI 和机器学习域,而不是更加面向对象的编程语言 C 等甚至如 R 语言#。
底部行是每个微服务可以有不同的内部体系结构,能根据不同的设计模式。 并非所有微服务应使用来实现高级的 DDD 模式,因为,将会过度工程它们。 同样,不应作为 CRUD 组件实现包含不断变化的业务逻辑的复杂微服务或您可以得到质量较低的代码。
新体系: 多个体系结构模式和 polyglot 微服务
有许多软件架构师和开发人员使用的体系结构模式。 以下是一些 (即混合体系结构样式和体系结构模式):
- 简单 CRUD,单层,单层。
- 传统 N 分层 。
- 域驱动设计 N 分层 。
- 清理体系结构 (如用于 eShopOnWeb )
- 命令和查询责任分离 (CQRS)。
- 事件驱动的体系结构 (EDA)。
你也可以生成与许多技术和语言,如 ASP.NET 核心 Web Api、 NancyFx、 ASP.NET 核心 SignalR (适用于.NET 核心 2)、 F 的微服务#,Node.js、 Python、 Java、 c + +、 GoLang,和的详细信息。
重要的一点是任何特定的体系结构模式或样式,也不任何特定的技术,最适合所有情况。 图 8-3 显示了一些方法和技术 (尽管不是在任何特定的顺序),无法在不同的微服务中使用。
图 8-3 。 多体系结构模式和 polyglot 微服务世界
中所示图 8-3,应用程序中许多微服务组成 (绑定上下文中在域驱动设计术语中或只需"子系统"作为自治微服务),您可能会以不同的方式实现每个微服务。 每个可能具有不同的体系结构模式,并使用不同的语言和具体取决于应用程序的性质、 业务需求和优先级的数据库。 在某些情况下可能是相似的微服务。 但这不是通常情况下,因为每个子系统的上下文边界和要求通常不同。
例如,对于简单 CRUD 维护应用程序,它可能毫无意义设计和实现 DDD 模式。 但核心域或核心业务,你可能需要应用更高级的模式为处理独特业务的不断变化的业务规则的复杂性。
尤其是当你处理大型应用程序由多个子系统,不应该应用基于单个体系结构模式同一个顶级体系结构。 例如,CQRS 不应作为整个应用程序的顶级结构应用,但可能适用于一组特定的服务。
没有任何银级的项目符号或每个给定的用例的正确的体系结构模式。 不能有"一个体系结构模式规则其全部。" 具体取决于每个微服务构成的优先级,必须选择不同的方法对于每个,如以下各节中所述。
以前 下一步
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论