简介
Beef 框架主要是为了支持API开发的工业化而创建的。
一种让软件开发人员直接专注于加速交付业务价值的方式;以更高的质量和更低的总体成本持续产出。
主要的工业化目标是:
- 价值 - 专注于业务价值,而不是样板代码
- 加速 - 提高速度;降低成本和缩短上市时间
- 简单 - 提高有效使用率并最小化学习成本
- 标准化 - 增加知识资源池
- 一致性 - 提高整体质量和可维护性
- 灵活性 - 随时间推移轻松实现创新和演进
- 信心 - 缩短交付时间和降低风险
演示
以下视频(包含声音)提供了 Beef 及其功能的高级演示。
https://github.com/Avanade/Beef/assets/12836934/693d4839-dfde-4360-9994-33f8dc10e3a1
第5版
注意: Beef 的一个新的主要版本 第5版 于2023年1月26日发布。示例已相应更新,相关文档也已更新。因此,之前的版本(v4.x)的开发将在很大程度上停止;只会解决重大问题(一段时间内)。新版本主要是对底层运行时的重大重构(改进和简化),尽管努力将从v4升级的影响降到最低,但这不可避免。我们提供了指导,以帮助在适用的情况下从v4.2.x升级到v5.x。
组成
Beef 本质上是代码生成引擎和解决方案编排,最终依赖于以下功能以标准化(尽管有些固执己见)的方式实现最终功能和测试:
- CoreEx - 提供核心运行时功能(扩展.NET core);
- UnitTestEx - 提供扩展的单元和域内集成测试;
- DbEx - 提供扩展的数据库管理功能;
- OnRamp - 提供底层代码生成引擎功能。
在5.x版本之前,Beef 包罗万象。这些功能已被提取、简化并重构为独立的一流框架,并制作成上述列出的存储库。这允许它们独立于 Beef 使用和维护;因此,提供了更多的重用机会,而不是全有或全无。
快速企业级API开发
由于 Beef 的架构、支持的框架和包含的代码生成功能,企业级API可以在几个小时内以标准化和一致的方式开发,而不是几天。
创建的API将具有以下开箱即用的功能,开发人员只需付出很少的努力,因此开发人员可以专注于关键的业务价值:
- 丰富的实体(DTO)功能,包括
INotifyPropertyChanged
、IEditableObject
、IEquatable
、ICopyFrom
、ICleanUp
、IPrimaryKey
等。 - 丰富的引用数据功能,包括缓存、优化序列化和增强的API端点。
- 丰富的验证功能,简化并确保数据完整性和一致性。
- 以标准化方式对数据库(存储过程和Entity Framework)、Cosmos DB和HttpAgent进行CRUD(创建、读取、更新和删除)操作。
- 分页(跳过和获取)以及结果总数,从API一直流向底层数据源,保持一致和无缝。
- ETag(并发)和
If-Match
/If-None-Match
处理。 - JSON响应字段过滤(包含/排除)以最小化结果有效负载大小(例如
$fields=firstname,lastname
) - 以简化和一致的方式支持HTTP Patch(在需要时)。
- 端到端域内集成测试方法使有效测试能够轻松快速地构建。
- 事件发布(和订阅)以实现事件驱动架构。
- 运行时功能可以使用开箱即用的.NET框架依赖注入(DI)功能添加(在适用的情况下)。
- 使用DbEx自动化和管理数据库设置、配置和部署的方法和工具。
要实现这些包含的功能,实际上需要花费数月/年的时间来构建和测试;这些功能可供开发人员立即使用,如果愿意,也可以贡献回来。这些功能和实现受到了Microsoft云应用程序最佳实践的影响;具体来说:
要开始使用,提供了一个.NET Core模板功能,使您能够在几分钟内启动并运行解决方案。
架构
Beef 的开发旨在鼓励应用程序架构中微服务(API)的分层和分层的标准化和工业化。
基于API的领域驱动、渠道无关的架构
概念架构如下; Beef 专门针对API层的实现。
主要概念如下:
-
渠道无关 - API基于关键实体及其可执行的操作:
- API代表关键信任边界;因此,它们不对消费者做任何假设。API将始终验证请求数据,并包含应用程序的功能业务和编排规则。
- API不应该开发来服务特定的用户界面交互;因为API对消费者是不可知的。消费者有责任协调API调用。
-
基于领域 – API基于并封装了功能领域的功能:
微服务
创建基于领域的API的架构模式:
- 是一种软件架构风格,其中复杂的应用程序由小型、独立的进程组成,这些进程使用与语言无关的API相互通信。
- 这些服务很小、高度解耦,专注于完成一小部分任务,有助于模块化系统构建方法。
- 实现独立性:
- 松耦合 – 应该有自己的持久性存储库;数据是复制(同步)的,而不是共享的;最终一致性;没有分布式事务。
- 多语言持久性/编程 – 使用最适合存储需求的持久性存储库;使用混合编程语言(适合目的)。注意: Beef 提供了C# / .NET实现方法作为一种选择。
- 最终一致性 - 在大多数情况下,最终一致性就足够了;很少需要实时分布式事务完整性(尽管通常是期望的)。异步消息系统(如队列或服务总线)可以用于编排跨域数据(最终)一致性。
"微"并不意味着代码行数;而是域内的有界概念/业务能力。 - http://herdingcode.com
分层
该架构支持基于领域的渠道无关的微服务方法。API服务端点代表业务(域逻辑)层的轻量级外观,该层最终负责完成请求。
以下代表该架构规定的分层:
基于此架构,使用 Beef 创建的.NET解决方案应遵循规定的解决方案结构。
上面的每个关键层/组件都进行了进一步详细说明(Xxx
表示实体名称);通过提供的链接可获得每个层的更多文档:
- 实体(DTO) -
Xxx
- 服务代理 -
XxxAgent
- 服务接口 -
XxxController
- 域逻辑 -
XxxManager
- 服务编排 -
XxxDataSvc
- 数据访问 -
XxxData
事件驱动
为了支持事件驱动架构的目标, Beef 启用了关键功能;向事件流(或等效物)发布(生产者)和订阅(消费者)事件(消息)。
-
生产者/发布者 - 事件发布集成到API处理管道中;这在数据(当利用事务性发件箱模式时)或服务编排层中启用,以确保方法的一致性。 Beef 在很大程度上与底层事件/消息基础设施(事件流)无关,必须由开发人员实现(除非提供,请参阅Azure ServiceBus)。
-
消费者/订阅者 - 然后实现事件订阅者以侦听来自底层事件/消息基础设施(事件流)的事件并执行相关操作。鼓励事件订阅者通过托管 Beef 功能来重用底层逻辑以实现。域逻辑层可以重新利用来执行接收事件时的底层业务逻辑(在订阅域的上下文中)。
此外, Beef 具有支持(和生成)事务性发件箱模式的功能,当需要_可靠_发送事件时(没有消息丢失);即在底层数据更新的上下文中保证至少一次发送语义(目前仅支持数据库存储库)。
框架
创建了一个全面的框架来支持定义的架构,封装和标
解决方案
代码生成
-
实体驱动 (.NET C#)
-
数据库驱动 (数据库)
可能感兴趣的外部链接
- 版本控制 - 文章, 实现 - Beef 对版本控制方法和/或实现没有特定支持或意见。
- 领域驱动设计 - 维基百科, Fowler, 微软撰写的文章: 文章, 文章, 文章 和 文章 - Beef 鼓励DDD方法,这就是为什么_实体_命名和约定在其中是基础的原因。
许可证
Beef 是根据 MIT 许可证 开源的,可以免费用于商业用途。
入门
要开始使用 Beef,您不需要克隆或复刻存储库;您只需要使用规定的解决方案结构创建一个包含底层项目的解决方案,包括引用适当的 NuGet 包。为了加速这一过程,提供了 .NET Core 模板功能,使您能够在几分钟内开始使用。
请参阅以下示例,了解端到端的解决方案/项目创建;每个示例都演示了相同的 API 功能,但利用不同的数据源来实现:
否则,请按照以下示例教程进行操作,这些教程将提供更深入的演练,解决定义的功能问题:
My.Hr
- 针对 SQL 数据库的微服务,同时使用存储过程和实体框架。MyEf.Hr
- 针对 SQL 数据库的微服务,使用实体框架。Cdr.Banking
- 针对 Azure CosmosDB 数据源的微服务。Xyz.Legacy
- 针对旧数据库的 CDC 实现,将消息发布到 Azure 服务总线。
贡献
贡献的最简单方式之一是参与 GitHub 问题的讨论。您也可以通过提交带有代码更改的拉取请求 (PR) 来做出贡献。
编码指南
最一般的指南是我们使用所有 VS 默认设置进行代码格式化;如有疑问,请遵循现有代码库的编码约定。
- 使用四个空格缩进(不使用制表符)。
- 对私有字段使用
_camelCase
。 - 除非绝对必要,否则避免使用
this.
。 - 始终指定成员可见性,即使它是默认的(例如,
private string _foo;
而不是string _foo;
)。 - 开括号 (
{
) 另起一行(单行语句的if
不需要括号)。 - 使用任何可用的语言特性(表达式主体成员、throw 表达式、元组等),只要它们使代码可读、可管理。
- 所有方法和属性都必须包含 XML 文档注释。私有方法和属性只需要指定 summary 作为最低要求。
更多指导请参见 ASP.NET Core 工程指南。
测试
NUnit 用于单元测试。
- 每个完成的 bug/功能都需要提供测试。
- 测试只需要存在于需要由 QA 验证的问题(例如,不是任务)。
- 如果有一个场景太难测试,则不需要为其提供测试。
- "太难"由整个团队决定。
代码审查和签入
为了确保只有最高质量的代码进入项目,请将所有代码更改作为 PR 提交到 GitHub。这包括运行时代码更改、单元测试更新和端到端演示的更新。
例如,仅为单元测试更新发送 PR 可能看起来是浪费时间,但单元测试与产品代码同样重要,因此审查对它们的更改也同样重要。这也有助于为您的更改创建可见性,以便其他人可以观察正在发生的情况。
优点很多:提高代码质量,更多地了解更改及其潜在影响,避免重复工作,并创建对各个领域正在取得的进展的普遍认识。