- 后端
- 工作流自动化
- 流程编排
- 低代码
【免费下载链接】elsa-core
The Workflow Engine for .NET
本篇指南以仓库内 doc/codebase/STRUCTURE.md 为骨架,系统梳理 elsa-core(.NET 工作流引擎)的代码库组织方式:顶层目录各自承担什么职责、应用入口如何装配、功能模块如何划分边界、测试与构建体系如何分层。读完本文,你可以快速定位任意功能(工作流、表达式、持久化、外部认证等)的源码位置,理解 Elsa 以模块为单位的演进方式,并掌握"从功能反查代码"的导航方法。
一、顶层布局速览:一条主线、七个分区
elsa-core 是一个大型多项目仓库,顶层以src/为源码主体,配合test/、build/、specs/等辅助分区。官方文档给出的顶层地图如下:
| 路径 | 职责 | 依据 |
|---|---|---|
| src/apps/ | 可运行的应用程序宿主(Host) | Elsa.sln |
| src/common/ | 共享基础设施 | Elsa.sln |
| src/modules/ | 功能与领域模块 | Elsa.sln |
| src/clients/ | API 客户端契约 | src/clients/Elsa.Api.Client |
| test/ | 单元、集成、组件与性能测试 | test/Directory.Build.props |
| build/ | NUKE 构建自动化 | build/Build.cs |
| specs/ | 功能规格与规划文档 | specs/012-weaver-grounding-tools/plan.md |
其中src/下的四个分区(apps / common / modules / clients)统一收编进根解决方案 Elsa.sln;所有src项目共享 src/Directory.Build.props,该文件继承仓库根的 Directory.Build.props 并引入 src/Fody.props,同时将目标框架统一为net8.0;net9.0;net10.0。这意味着每个模块项目都不必重复声明框架版本与包版本——框架统一在这里收敛,包版本则由仓库级 Directory.Packages.props 集中管理(Central Package Management)。
二、应用入口:src/apps/ 下的可运行宿主
src/apps/是运行时(runtime)的入口层。从源码结构看(src/apps),当前包含四类宿主项目:
Elsa.Server.Web/:面向服务端 API 场景的 Web 宿主,内含 5 个.cs文件、4 个.json配置与多个.elsa工作流定义文件;Elsa.ModularServer.Web/:用于验证"模块化组装"能力的宿主,9 个.cs文件、4 个.json,演示如何按需挂载模块;Elsa.Server.LoadBalancer/:负载均衡场景的宿主示例;Elsa.SamplePackage/:用于验证打包与消费流程的示例项目。
项目级配置在 src/apps/Directory.Build.props 中统一定义。从架构角度理解:Elsa 的可执行能力几乎全部来自模块装配,apps 项目本身很薄,主要负责组合 Feature、配置中间件与启动 Web 服务器——这正是"模块化运行时"的体现。
三、共享基础设施:src/common/
src/common/放置与具体业务无关的共享基础设施,是各模块复用的底座。当前包含(src/common):
Elsa.Api.Common/:API 通用构件(30 个.cs文件);Elsa.Features/:Feature 装配框架——整个 Elsa 的模块化加载机制依赖它,模块通过实现/注册 Feature 来声明依赖并暴露能力;Elsa.Mediator/:进程内消息中介(79 个.cs文件),为模块解耦提供事件与命令通道;Elsa.Testing.Shared/、Elsa.Testing.Shared.Component/、Elsa.Testing.Shared.Integration/:供组件级与集成级测试复用的宿主与夹具。
可以推断:任何新模块想要获得"可被宿主装配、可与其他模块解耦通信、可被测试托管"的能力,都需要依赖这里的Elsa.Features与Elsa.Mediator。
四、功能与领域模块:src/modules/(仓库主体)
src/modules/是 elsa-core 的主体(当前约 70 个模块项目),按"一个功能一个模块、一个模块一族项目"的方式组织。模块族可归纳为几大类:
- 工作流核心:
Elsa.Workflows.Core(510 个.cs)、Elsa.Workflows.Management、Elsa.Workflows.Runtime、Elsa.Workflows.Api,以及Elsa.Workflows.Runtime.Distributed/Elsa.Workflows.Runtime.Dashboard; - 表达式与脚本:
Elsa.Expressions及 C# / JavaScript / Liquid / Python 各分支,另有Elsa.Dsl.ElsaScript(Elsa 自定义 DSL 与 ANTLR 语法); - 持久化:
Elsa.Persistence.EFCore家族(MySql / Oracle / PostgreSql / SqlServer / Sqlite 五类数据库适配),以及新一代的Elsa.Persistence.VNext家族(含 MongoDb / PostgreSql / SqlServer / Sqlite / Runtime / Relational); - 连接与机密:
Elsa.Connections、Elsa.Secrets及其 EFCore 持久化分支; - 外部认证:
Elsa.ExternalAuthentication、Elsa.ExternalAuthentication.OpenIdConnect、Elsa.ExternalAuthentication.Persistence.EFCore(及各数据库适配)、Elsa.ExternalAuthentication.Secrets; - 其他领域能力:
Elsa.Http与Elsa.Http.Webhooks、Elsa.Scheduling、Elsa.Identity、Elsa.Tenants、Elsa.Labels、Elsa.UserTasks、Elsa.Alterations、Elsa.Bpmn、Elsa.AI.*(Copilot / Host / Persistence)、Elsa.Diagnostics.*(OpenTelemetry / StructuredLogs / ConsoleLogs)、Elsa.Resilience、Elsa.Caching、Elsa.KeyValues、Elsa.SasTokens、Elsa.Shells.Api等。
模块内组织约定:每个模块目录内部通常再按Contracts / Services / Endpoints / Stores / Extensions / Features分层(详见下文"命名与组织规则"),从而让"契约—实现—端点—存储—装配"一目了然。
五、API 客户端契约:src/clients/Elsa.Api.Client
src/clients/目前只有一个项目 Elsa.Api.Client(236 个.cs文件)。它的定位是向后兼容的客户端 DTO 与 HTTP 契约,而不是持久化实体或服务端内部模型。也就是说:
- 服务端模块(
src/modules/*)通过它定义对外暴露的请求/响应模型; - 外部程序可以引用这个程序集,直接获得强类型的工作流 API 客户端;
- 契约稳定是它的最高优先级——模块内部重构时,只要不破坏
Elsa.Api.Client的公开 DTO,客户端消费者就不会感知。
这也解释了 STRUCTURE.md 中"Elsa.Api.Client允许放客户端 DTO,禁止放持久化实体"的边界要求。
六、测试体系:test/ 的四层金字塔
test/目录按测试层级组织,各层有独立的 test/Directory.Build.props 与 test/Directory.Build.targets:
| 层级 | 目录 | 代表项目 |
|---|---|---|
| 单元测试 | test/unit/ | Elsa.Workflows.Core.UnitTests、Elsa.Activities.UnitTests、Elsa.Expressions.UnitTests等 40+ 个项目 |
| 集成测试 | test/integration/ | Elsa.Workflows.IntegrationTests(187 个.cs+ 71 个.json)、Elsa.Http.IntegrationTests等 |
| 组件测试 | test/component/ | Elsa.Workflows.ComponentTests(141 个.cs) |
| 性能测试 | test/performance/ | Elsa.Workflows.PerformanceTests |
| 其他 | test/workers/、test/TlsSmoke/ | 后台工作进程与 TLS 冒烟验证 |
配合共享测试库(Elsa.Testing.Shared*),每个被测模块几乎都有对应的UnitTests/IntegrationTests项目,形成"一模块一测试"的镜像结构。
七、构建自动化:build/(NUKE)
build/目录承载 NUKE 构建体系(build/Build.cs、build/Build.CI.GitHubActions.cs、build/_build.csproj)。仓库根部的 build.sh / build.ps1 / build.cmd 是 NUKE 引导入口。从结构推断,构建任务(还原、编译、打包 NuGet、运行测试)都被集中定义在Build.cs中,CI(GitHub Actions)通过 .github 下的工作流调用 NUKE 目标,而非散落的 shell 脚本。
八、规格与规划:specs/
specs/存放功能规格与实施计划,每个功能一个编号目录,典型的目录结构包含spec.md、plan.md、tasks.md、research.md、contracts/、checklists/等。例如 specs/012-weaver-grounding-tools/plan.md 即被 STRUCTURE.md 引用为 specs 分区的证据。这意味着 Elsa 的新功能遵循"先有规格、再进源码"的开发节奏,阅读规格目录可以预知后续演进方向。
九、入口点与端点发现:以外部认证为例
STRUCTURE.md 明确了两条重要的工程事实:
- 主运行时入口是
src/apps/下的应用程序项目——真正Main方法所在,模块本身不直接可运行; - 端点发现(endpoint discovery)是模块化的——例如外部认证的 identity-link 端点集中位于 src/modules/Elsa.ExternalAuthentication/Endpoints/IdentityLinks/IdentityLinkEndpoints.cs。
沿此线索可以在源码中验证"外部认证如何被组装":AddExternalAuthenticationServices扩展方法定义于 src/modules/Elsa.ExternalAuthentication/Extensions/ServiceCollectionExtensions.cs,并通过 src/modules/Elsa.ExternalAuthentication/Features/ExternalAuthenticationFeature.cs 的 Feature 机制注册;若要换成 EF Core 持久化实现,则由 src/modules/Elsa.ExternalAuthentication.Persistence.EFCore/Extensions/ServiceCollectionExtensions.cs 提供可替换的注册。模块的 README(src/modules/Elsa.ExternalAuthentication/README.md)给出了完整的装配示例:
services.AddElsa(elsa => { elsa.UseExternalAuthentication(feature => { feature.ConfigureOptions = options => configuration.GetSection("ExternalAuthentication").BindExternalAuthenticationOptions(options); }); }); services.AddOpenIdConnectExternalAuthentication();从端点目录看(src/modules/Elsa.ExternalAuthentication/Endpoints),外部认证模块内部按职责拆出了多个端点组:Broker/(发起/回调/令牌交换/登出)、IdentityLinks/(身份链接)、Sessions/、Descriptors/、Connections/、Previews/。这正好演示了"端点发现模块化 + 端点按子域组织"的组合拳:要找某个 HTTP 端点的实现,先锁定模块,再按端点语义找对应子目录即可。
十、模块边界:什么东西应该放在哪里
STRUCTURE.md 用一张"边界表"明确回答了一个模块设计中最常被问的问题——哪些代码属于哪个模块。原表完整如下:
| 边界 | 属于这里 | 绝不允许放这里 |
|---|---|---|
Elsa.ExternalAuthentication | Broker 编排、契约、内存态存储、安全的 HTTP DTO | 特定协议提供方的行为 |
Elsa.ExternalAuthentication.OpenIdConnect | OIDC 回调与 provider 适配行为 | Elsa 用户授权策略 |
Elsa.ExternalAuthentication.Persistence.EFCore | 持久化实体与 store 实现 | UI 展示 |
Elsa.Api.Client | 向后兼容的客户端 DTO 与 HTTP 契约 | 持久化实体 |
从中可以提炼出三条通用原则:
- 协议与编排分离:
OpenIdConnect这类适配器只关心协议细节,不得越界定义 Elsa 自身的授权策略; - 持久化与展示分离:EF Core 模块只产出 durable entities 与 store,UI 相关代码不得混入;
- 契约与实现分离:
Elsa.Api.Client作为对外契约层,内部实体永远不能泄漏进来。
这套边界不是纸面规则——仓库中外部认证的"一个功能族 + 多数据库适配项目"(Elsa.ExternalAuthentication.Persistence.EFCore.MySql/Oracle/PostgreSql/SqlServer/Sqlite)正是按此拆分的实际落地。以Elsa.ExternalAuthentication模块为例,其职责限定为"协议无关的 Broker 编排":它组合部署安装的 provider 适配器、连接来源、未链接身份策略、权限授权来源、机密解析器、原子流存储与 Elsa 令牌签发,但不保留 provider 令牌、不把外部声明当作 Elsa 权限(除非显式配置的授权来源做了映射或约束)——这与边界表完全一致。
十一、命名与组织规则
STRUCTURE.md 还固定了三条贯穿全仓库的工程规范:
- PascalCase:所有 C# 文件与公开类型一律使用 PascalCase 命名;
- 先功能、后分层:模块按功能组织,模块内部再按
Contracts / Services / Endpoints / Stores等角色分层; - 命名空间跟随文件夹,使用文件级作用域(file-scoped):每个文件一个
namespace声明,且命名空间路径与物理目录保持一致。
这些规则的执行依据见 .editorconfig(代码风格与分析规则)、src/Directory.Build.props(LangVersion=latest、Nullable=enable、ImplicitUsings=enable)以及仓库根 Directory.Build.props(文档生成与分析模式、TreatWarningsAsErrors=false等)。另外仓库还配套 IDE 级配置 Elsa.sln.DotSettings,与命令行分析一起约束代码风格。
十二、证据清单:如何自行复核
STRUCTURE.md 结尾给出的证据文件,可作为读者进一步深入仓库的入口:
- Elsa.sln:顶层地图(apps/common/modules 归属)的直接依据;
- src/modules/Elsa.ExternalAuthentication/Extensions/ServiceCollectionExtensions.cs:
AddExternalAuthenticationServices组合外部认证的入口; - src/modules/Elsa.ExternalAuthentication.Persistence.EFCore/Extensions/ServiceCollectionExtensions.cs:EF Core 持久化的可选替换注册;
- .editorconfig:命名与风格规则的强制执行配置。
总结:一条"从功能到代码"的导航路径
综合全文,在 elsa-core 中定位任何功能的推荐路径是:先看 specs/ 是否有该功能的规格与计划 → 在 src/modules/ 找到对应模块族 → 模块内按Contracts / Endpoints / Stores深入实现 → 到 src/clients/Elsa.Api.Client 核对对外契约 → 到 test/ 对应层级查看测试佐证 → 最后在 src/apps/ 看宿主如何装配该模块。沿着这条链路,配合 STRUCTURE.md 的边界规则,你可以在大型代码库中快速建立"功能 → 模块 → 端点 → 契约 → 测试 → 宿主"的完整心智地图。
- 后端
- 工作流自动化
- 流程编排
- 低代码
【免费下载链接】elsa-core
The Workflow Engine for .NET
相关推荐
V8 仓库结构全解析:从 src/ 源码布局到 docs/ 设计文档的导航指南
V8 仓库结构全解析:从 src/ 源码布局到 docs/ 设计文档的导航指南 本指南以 V8 仓库的目录结构为核心主线,系统梳理 src/ 下各子系统的职责边
语言运行时编译器JIT编译解释器内存管理vscode-cpptools代码导航:继承层次结构
vscode cpptools代码导航:继承层次结构 1. 继承层次结构导航概述 在大型C/C++项目开发中,类(Class)与接口(Interface)的继承
开发工具调试器Electron 源码目录结构完全指南:解析 Chromium 宿主下的 src/electron 分层代码组织
Electron 源码目录结构完全指南:解析 Chromium 宿主下的 src/electron 分层代码组织 本文以 Electron 官方开发文档 sou
桌面应用跨平台前端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考