功能实现任务解析与架构指南)
后端工作流自动化流程编排低代码【免费下载链接】elsa-coreThe Workflow Engine for .NET项目地址https://gitcode.com/gh_mirrors/el/elsa-core点击查看免费下载导读本文以specs/012-output-converters/特性规格中的任务清单tasks.md为骨架系统梳理 Elsa Workflows.NET 工作流引擎中可扩展活动输出转换器Extensible Activity Output Converters从契约设计、序列化、运行时调用、定义校验、REST 发现 API、到 Studio 可视化配置的完整落地过程。读者将掌握该特性的数据模型、七个实施阶段与任务依赖关系、四个用户故事的核心验收场景以及如何在源码中定位对应的契约、实现与测试证据从而具备在 Elsa Core 中开发或扩展输出转换器的实战能力。1. 特性背景为什么要引入活动输出转换器在 Elsa Workflows 中活动Activity产生原生 Activity Output通过**输出绑定Output Binding**将值写入变量或工作流输出workflow output。历史上绑定只能原样赋值如果目标变量需要与活动原生输出不同的表示例如把对象格式化为文本、把时间戳转换为指定格式的字符串作者只能靠表达式或额外的活动去处理。该特性在活动输出与绑定目标之间引入一个显式、同步、可选的转换边界转换只作用于绑定目标Bound Value活动的原生输出始终保持不变转换是显式选择的通过稳定的 Converter ID绝不依据源/目标类型自动推断未配置转换器的绑定继续走原有热路径序列化 JSON 形状与既有行为完全不变spec.md FR-001~FR-008。设计约束贯穿整个任务清单不允许把转换行为加到活动输入activity inputs或一般表达式求值中也不做异步转换器、转换器链、开放式泛型匹配或自动选择见 spec.md 的 Out of Scope。2. 核心数据模型与实体Phase 2 的产物从>{ typeName: String, memoryReference: { id: resultVariable }, converter: { id: sample.to-text, settings: { format: compact } } }关键约定配置不持久化实现类型名、实例、描述符或展示元数据FR-004未配置转换器的定义保持原有 JSON 形状FR-003这正是向后兼容的根基。2.3 转换器注册RegistrationDescriptor不可变描述符ServiceKey精确的 Converter ID用于 keyed DI 解析ServiceLifetimeTransient / Scoped / Singleton 三种生命周期。唯一性规则完全相同ordinal、大小写敏感的 ID 必须唯一仅大小写不同的 ID 也禁止注册FR-013注册期即确定性失败不依赖注册顺序。2.4 转换器描述符Descriptor服务端自有的发现元数据源码 OutputConverterDescriptor.csId稳定语义身份SourceType/ResultType支持的源 CLR 类型与声明的结果 CLR 类型DisplayName/Description可发现的展示文本与可选描述SettingsSchema可选的克隆 JSON Schema。API 投影会用注册的类型别名或安全类型名替换 CLR 类型并移除一切服务注册数据FR-035。2.5 转换上下文Conversion Context不可变的调用入参对应源码OutputConversionContextValue非空的原生活动输出SourceType声明的活动输出类型DestinationType解析出的目标声明类型Settings不可变/已克隆的 JSON 设置。上下文中不含工作流执行对象、也不含服务提供器FR-022这从根上杜绝了转换器对工作流执行的隐性修改。2.6 目标DestinationId内存引用或工作流输出身份Type解析出的 CLR 类型AllowsNull引用类型与NullableT为 true其余值类型为 falseKind变量或工作流输出。定义期解析沿最近的变量容器作用域再向外到工作流输出运行时解析使用声明的内存块元数据T020 的 OutputBindingDestinationResolver.cs。2.7 输出转换错误Output Conversion Error结构化的活动故障T009 的OutputConversionException与失败阶段枚举包含ConverterId、StageResolution / SettingsValidation / SourceCompatibility / Invocation / ResultValidation、ActivityId、ActivityType、OutputName、DestinationId、SourceTypeName、DestinationTypeName与可选的InnerException。安全字段才被复制进持久化异常元数据原生值与原始设置绝不进入默认错误消息FR-032。2.8 状态转换data-model.md 给出的状态机即运行时的核心逻辑骨架对应 T024 在 ActivityExecutionContext.cs 中的编排Unconfigured Binding └─ assign native value using existing path Configured Binding ├─ record native output ├─ native null → validate destination nullability → write null └─ non-null ├─ resolve registration and destination ├─ validate source, destination, and settings ├─ invoke converter ├─ validate result and nullability ├─ success → write Bound Value └─ failure → fault activity; destination unchanged3. 运行时扩展契约Runtime Extension Contractcontracts/runtime-contract.md 定义了公开的 C# 契约对应任务 T008 在src/modules/Elsa.Workflows.Core/Contracts/下新增的接口。源码中的 IOutputConverter.cs 即为该契约的实际实现public interface IOutputConverter { /// Converts a non-null native output value into a bound value. object? Convert(OutputConversionContext context); /// Validates optional per-binding settings. IEnumerablestring ValidateSettings(JsonElement? settings) []; }接口要求实现同步、确定性、无副作用FR-025源码 XML 注释亦明确说明且ValidateSettings的返回消息不得包含敏感设置值。注册通过公开的服务注册扩展完成任务 T010 的 OutputConverterServiceCollectionExtensions.csservices.AddOutputConverterTConverter( descriptor, ServiceLifetime.Scoped);必要的语义约束runtime-contract.md 与 spec FR-012~FR-024Converter ID 查找是ordinal、大小写敏感的完全重复与仅大小写不同的注册都失败描述符兼容性判定源类型可被声明输出类型赋值base/interface assignability、结果类型可赋给目标类型FR-017/FR-018转换器实现从当前活动执行作用域按 ID 解析keyed DIT022Settings 与 Schema 在存储/暴露前克隆空原生值直接绕过ConvertFR-008实现必须是确定性的、无副作用的。研究文档research.md还解释了为何采用 keyed DI 而非单例字典单例字典会违反 scoped 生命周期而解析未加 key 的实现类型在一个实现服务多个 ID时会产生歧义。4. 任务分阶段详解七个 Phase 的落地路径任务清单 tasks.md 把整个特性组织为 7 个阶段每个阶段以先写失败测试、再实现、后验证检查点的方式推进遵循 FR-042 与仓库的测试纪律测试必须先于实现失败。Phase 1SetupT001~T003T001在 Directory.Packages.props 增加集中版本化的JsonSchema.Net依赖并从 Elsa.Workflows.Core.csproj 引用。选型理由见 research.mdCore 此前没有 JSON Schema 校验器而临时子集无法满足对外承诺的标准合规契约JsonSchema.Net 适配仓库的 .NET 目标与 System.Text.Json 模型。T002/T003在 Core 单元测试目录test/unit/Elsa.Workflows.Core.UnitTests/OutputConverters/与 Studio 测试目录下建立输出转换器测试文件夹与共享 fixture。Phase 2基础契约与持久化T004~T015这一阶段是所有用户故事的前置阻塞项核心产出已在第 2 节列出。测试先行包括T004普通与省略配置的序列化往返测试OutputJsonConverterTests.csT005合成输出synthetic-output序列化测试SyntheticPropertiesWriterTests.csT006注册表身份与兼容性测试OutputConverterRegistryTests.cs。实现侧T010 在 OutputConverterRegistry.cs 实现严格描述符注册表T011 在 WorkflowsFeature.cs 与 ShellFeatures/WorkflowsFeature.cs 同时注册注册表、解析器、校验器与调用器基础设施兼顾普通宿主与 shell 宿主两种模式T014 同步更新 API 客户端的活动输出往返ActivityOutput.cs。检查点转换器配置可往返、省略 JSON 时形状不变、注册稳定且可发现。Phase 5 之后的实施策略与依赖关系任务清单最后给出了实施策略MVP 与增量交付与依赖/并行关系可直接作为开发排期的依据MVP完成 Setup、Foundational、User Story 1 及 User Story 2 的注册部分验证转换值交付、原生输出保留、原子失败、scoped 解析与无转换器旧路径增量交付五步①契约与持久化 → ②运行时转换与扩展注册 → ③定义校验与持久故障 → ④描述符 API/客户端与 Studio 创作 → ⑤横切加固与完成审计。依赖关系Setup 先于基础契约基础契约阻塞所有用户故事US1 与 US2 可在基础之后并行但 US1 的端到端测试依赖 US2 完成的注册契约US3 依赖 US1/US2 的运行时调用与注册表行为US4 的 API 工作依赖描述符注册表Studio 工作依赖 API 客户端模型收尾与完成审计依赖全部四个用户故事。并行机会基础模型/接口/错误任务可在注册表集成前并行运行时测试、目标解析测试与组件测试可并行编写契约稳定后 API/客户端与 Studio 组件测试脚手架可并行Core 与 Studio 构建在跨仓库完成审计前可独立运行。5. 用户故事 1交付转换后的绑定值P1T016~T025目标只转换目标值保留原生活动输出观察面与默认热路径。任务 T016~T018 分别在 OutputBindingDestinationResolverTests.cs、OutputConverterInvokerTests.cs 与 ActivityExecutionContextOutputConversionTests.cs 覆盖目标解析、作用域调用、设置校验、空值旁路、结果校验、原子性以及原生注册 vs Bound Value无转换器查找场景T019 在组件测试 OutputConverterTests.cs 覆盖变量/工作流输出组件场景。实现侧的关键决策research.md运行时接缝转换编排放在ActivityExecutionContext.SetT024这是唯一同时拥有输出绑定与原生活动结果的集中边界先记录原生值这样转换失败时诊断信息依然完整绑定值写入路径T023在 ExpressionExecutionContextExtensions.cs 增加绑定专用的目标写入。原因是底层 setter 会调用Output.ParseValue它通过原生OutputT类型转换会撤销类型变更型转换——因此必须新增一个直接把已验证 Bound Value 写入输出内存引用与工作流输出字典的路径而不是全局改动Output.ParseValue避免影响既有输入/输出强转行为。验收场景来自 spec.md US1显式配置兼容转换器、活动产生非空原生值 → 变量收到转换值活动输出寄存器保留原生值绑定到工作流输出 → 工作流输出收到转换值日志与诊断仍报告原生值未配置转换器 → 沿用现有行为不触发发现/校验/调用配置的绑定收到 null → 绕过转换仅当目标允许 null 时才交付 null。检查点合法绑定收到转换值、观察面保留原生值、配置失败原子、未配置绑定走旧路径。6. 用户故事 2安全注册可复用转换器P1T026~T030目标给扩展开发者提供生命周期安全、有文档的注册与调用契约让扩展模块无需改动 Core 即可添加可发现、作用域正确的转换器。T026服务生命周期与多作用域测试OutputConverterRegistrationTests.csT027确定性参考转换器 fixtureReferenceOutputConverter.csT028补全公开 XML 文档与注册重载OutputConverterServiceCollectionExtensions.cs 与 Contracts 目录T029参考注册与使用覆盖OutputConverterRegistrationUsageTests.cs。验收要点spec.md US2唯一 ID 可精确选择重复或仅大小写不同 ID 注册确定性失败每绑定设置以不可变 JSON传入且无可变执行上下文/服务定位器scoped 依赖在每次独立的执行作用域内解析不缓存 scoped 实例FR-024描述符可缓存但缓存中不得持有 scoped 转换器实例或依赖。检查点扩展模块可添加可发现的 scoped 转换器无需修改 Core 或持久化其实现类型。7. 用户故事 3拒绝非法配置P2T031~T038目标静态配置错误尽早拒绝运行时部署漂移/转换失败产生上下文相关、隐私安全的活动故障。测试先行T031工作流定义校验测试ValidateOutputConvertersTests.csT032安全异常状态持久化测试OutputConversionExceptionStateTests.csT033运行时漂移与事故组件场景OutputConverterFaultTests.cs。实现侧T034 在 ValidateOutputConverters.cs 实现基于图的定义校验由WorkflowDefinitionValidating通知处理器访问物化工作流图在发布/导入验收时校验已配置绑定FR-026。选择该生命周期而非每次草稿保存的理由research.mdElsa 既有校验器是通知可扩展的且发布已会触发仅运行时校验则作者反馈太迟T035 在 WorkflowManagementFeature.cs 与 ShellFeatures 版本中注册定义校验T036 在 ExceptionState.cs 持久化安全的结构化转换元数据并由既有异常状态映射器填充。只复制窄接口的安全元数据把转换器异常保留为内部异常research.md自定义异常属性持久化后丢失而序列化任意Exception.Data可能泄露原生值或设置T037 在 API 客户端 ExceptionState.cs 镜像安全异常元数据。验收场景spec.md US3未知 ID / 不兼容声明类型 / 非法设置 / 未知目标类型 / 无目标 → 定义验收拒绝并给出可行动上下文已发布工作流在转换器缺失或失配的部署中执行 → 通过 Elsa 正常故障管线产生专用 Output Conversion ErrorFR-029无转换器专属重试机制转换器抛异常或返回非法结果 → 目标不变、原生 Activity Output 仍可获取、保留原始异常含敏感数据的输出/设置出错 → 默认错误消息排除原生值与原始设置。检查点静态非法定义被拒绝、部署漂移按正常方式故障、结构化安全元数据在持久化/API 映射后存活。8. 用户故事 4Studio 中发现与配置转换器P2T039~T054目标服务端自有发现 完整的 Studio 创作/往返FR-033~FR-039。这要求 Studio 消费描述符 API 而非维护硬编码目录FR-036。8.1 REST 描述符 API 与客户端T039~T044任务 T043 在 Endpoint.cs 实现了授权兼容描述符列表端点。契约见 contracts/rest-api.mdGET /descriptors/output-converters?sourceType{typeName}destinationType{typeName}授权read:* OR read:output-converters源码中对应WorkflowPermissions.DescriptorsOutputConvertersCoreVerbs.View两个查询参数均必填且必须是已注册的类型别名或可解析的安全类型名缺失或不可解析时返回 400源码TryResolveType的错误消息即对应契约无权限时 403成功响应中类型名被投影为别名或安全名绝不含实现类型、实例、工厂、生命周期或工作流定义中的设置值。成功响应示例{ items: [ { id: sample.to-text, sourceTypeName: Sample.Source, resultTypeName: String, displayName: Convert to text, description: Formats the source as text., settingsSchema: { type: object, properties: { format: { type: string, enum: [compact, indented] } } } } ] }客户端侧T041 在 Elsa.Api.Client/Resources/OutputConverters/ 新增请求/响应/模型与 Refit 契约T042 在 DependencyInjectionExtensions.cs 注册IOutputConvertersApi。Refit 接口rest-api.mdpublic interface IOutputConvertersApi { [Get(/descriptors/output-converters)] TaskListOutputConvertersResponse ListAsync( [Query] ListOutputConvertersRequest request, CancellationToken cancellationToken default); }8.2 Studio 创作行为T045~T054Studio 契约contracts/studio-contract.md规定了 Outputs 标签页的完整交互规则既有目标选择器保留目标身份与声明类型元数据T050 在 Outputs 的Models/下丰富绑定目标元数据选中类型化目标后用输出与目标类型名查询兼容描述符展示带None选项的可选转换器选择器选中转换器只把 ID 与设置写入活动输出 JSON清除转换器即移除可选 converter 对象只有不再兼容时才在目标变更时清除转换器无关活动属性的编辑原样保留转换器 JSON。设置编辑器T051 的 OutputConverterSettingsEditor.razor仓库内为 Studio 模块镜像路径有受支持的 object JSON Schema 时渲染字符串/数字/整数/布尔/enum/required/title/description/default 字段无 Schema 或不支持的构造时回退为原始 JSON 对象编辑器畸形或非对象 JSON 本地拒绝服务端定义校验消息保持权威并向作者呈现只读工作区不可修改转换器选择或设置。版本偏斜与健壮性T046、research.md取消/忽略目标切换时的过期描述符请求连接旧服务器时隐藏或禁用新控件但不删除已持久化的转换器配置已持久化的未知 Converter ID显示 ID 与校验状态而非静默清除Studio 自有标签与错误本地化服务端展示文本缺失时回退到 Converter ID。检查点Studio 作者可发现、选择、配置、保存、重开、校验与清除转换器且面向当前或旧服务器都不丢数据SC-005/SC-006。9. 收尾与横切验证Phase 7T055~T061本阶段证明向后兼容、隐私、性能、文档与跨仓库集成T055 性能基准OutputAssignmentBenchmark.cs 覆盖无转换器赋值基准。成功标准 SC-002 要求未配置绑定零转换器注册表查找、零转换器相关分配代表性输出赋值吞吐回归不超过 2%T056 版本偏斜与合成输出/工作流即活动覆盖在 OutputConverters/ 组件测试目录扩展场景T057 文档更新 doc/ 下的公开功能文档与 quickstart.mdT058~T060 构建验证运行 Core/Management/API/client/component/Studio 目标测试项目、dotnet build Elsa.sln及受影响 Studio 构建再运行更广的./build.sh Test任何既有/无关失败需附证据T061 完成审计对照 checklists/completion.md 审计 FR-001~FR-042 与 SC-001~SC-008 的实现与测试证据。快速验证路径可参考 quickstart.md注册确定性转换器 → 绑定活动输出到目标 → 选择转换器并配置 → 保存/重开 → 执行并核对绑定值为转换后文本、活动输出寄存器与日志为原生对象、转换器从工作流作用域解析、重放产生相同 Bound Value再通过未知 ID/不兼容目标/非法设置验证定义拒绝通过发布后删除注册验证正常故障与隐私安全。10. 事实边界与注意事项任务清单中标注了绝对路径的 Studio 测试文件如/Users/sipke/Projects/Elsa/elsa-studio/...属于独立 Studio 仓库当前仓库对应模块位于 src/studio/阅读时以当前仓库实际布局为准所有任务项在当前 tasks.md 中均已勾选[x]表明该特性在规格层面已完成闭环但不能据此推断具体发布版本或生产可用状态版本能力请以仓库实际发布物为准特性明确超出范围异步转换器、转换器链、自动选择/回退、开放式泛型匹配、活动输入转换、一般表达式结果强转、Core 自带大而全的生产转换器目录FR-041、Out of Scope。Core 只用测试/示例中的参考转换器演示扩展机制FR-040。11. 关键源码索引契约src/modules/Elsa.Workflows.Core/Contracts/IOutputConverter.cs、IOutputConverterRegistry.cs、IOutputConverterInvoker.cs、IOutputConverterSettingsValidator.cs模型src/modules/Elsa.Workflows.Core/Models/Output.cs、OutputConverterConfiguration.cs、OutputConverterDescriptor.cs、OutputConverterRegistration.cs服务src/modules/Elsa.Workflows.Core/Services/OutputConverterRegistry.cs、OutputConverterInvoker.cs、OutputConverterSettingsValidator.cs、OutputBindingDestinationResolver.cs运行时编排src/modules/Elsa.Workflows.Core/Contexts/ActivityExecutionContext.cs、src/modules/Elsa.Workflows.Core/Extensions/ExpressionExecutionContextExtensions.cs定义校验src/modules/Elsa.Workflows.Management/Handlers/Notifications/ValidateOutputConverters.cs发现 APIsrc/modules/Elsa.Workflows.Api/Endpoints/OutputConverters/List/Endpoint.cs、权限定义src/modules/Elsa.Workflows.Api/Permissions/WorkflowPermissions.csAPI 客户端src/clients/Elsa.Api.Client/Resources/OutputConverters/规格文档specs/012-output-converters/spec.md、plan.md、research.md、data-model.md、quickstart.md 及 contracts/、checklists/ 子目录赞分享后端工作流自动化流程编排低代码【免费下载链接】elsa-coreThe Workflow Engine for .NET项目地址https://gitcode.com/gh_mirrors/el/elsa-core点击查看免费下载相关推荐Elsa 3 输出转换器Output Converters完全指南在绑定边界同步、显式、可发现地转换 Activity 输出Elsa 3 输出转换器Output Converters完全指南在绑定边界同步、显式、可发现地转换 Activity 输出 本篇技术指南聚焦 Elsa后端工作流自动化流程编排低代码Elsa Workflows 输出转换同步绑定机制Activity Output 与 Bound Value 的边界设计深度解析Elsa Workflows 输出转换同步绑定机制Activity Output 与 Bound Value 的边界设计深度解析 导读 本文基于 Elsa W后端工作流自动化流程编排低代码Elsa Workflows 领域术语体系解析从输出转换到用户任务与外部身份认证Elsa Workflows 领域术语体系解析从输出转换到用户任务与外部身份认证 导读 本文面向使用 Elsa Workflows 构建 .NET 工作流引擎后端工作流自动化流程编排低代码上一篇5分钟掌握commitlint团队协作的Git提交规范终极指南下一篇CANN cann-samples SIMT 编程实战基于 Ascend C 实现固定 Shape 的一维与二维 Gather 算子创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考