Sparkdo.Runtime.Generators
0.0.1-preview.7
dotnet add package Sparkdo.Runtime.Generators --version 0.0.1-preview.7
NuGet\Install-Package Sparkdo.Runtime.Generators -Version 0.0.1-preview.7
<PackageReference Include="Sparkdo.Runtime.Generators" Version="0.0.1-preview.7" />
<PackageVersion Include="Sparkdo.Runtime.Generators" Version="0.0.1-preview.7" />
<PackageReference Include="Sparkdo.Runtime.Generators" />
paket add Sparkdo.Runtime.Generators --version 0.0.1-preview.7
#r "nuget: Sparkdo.Runtime.Generators, 0.0.1-preview.7"
#:package Sparkdo.Runtime.Generators@0.0.1-preview.7
#addin nuget:?package=Sparkdo.Runtime.Generators&version=0.0.1-preview.7&prerelease
#tool nuget:?package=Sparkdo.Runtime.Generators&version=0.0.1-preview.7&prerelease
Sparkdo.Runtime.Generators
Sparkdo.Runtime.Generators 是 Sparkdo Runtime 的底层 Roslyn 源生成与构建协议包。它把经过验证的 Runtime 工件闭包送入编译器,并仅在最终组合根生成 Sparkdo.Runtime.RuntimeCompositionTable。包同时携带 .targets、analyzer 和私有 MSBuild 任务程序集,因此项目不需要手写任务导入或管理中间清单。
新应用和 Runtime 包作者默认通过 Sparkdo.Runtime.Sdk 或已携带 SDK 的 Runtime 能力包接入本包,不需要直接引用 Sparkdo.Runtime.Generators。直接引用只保留给旧项目迁移、协议调试和需要显式控制底层构建协议的高级场景。本包不会扫描程序集或自动发现注册;任一输入不完整、冲突或无法静态解析时,构建以 SRR 诊断失败,不会退回到反射或运行时扫描。
包内容
| 资产 | 作用 |
|---|---|
analyzers/dotnet/cs/Sparkdo.Runtime.Generators.dll |
Roslyn 增量源生成器,仅根据受控的编译器输入验证并生成组合表 |
build/Sparkdo.Runtime.Generators.targets |
Runtime 工件收集、项目引用协议、清单/快照接线与矩阵验证 |
buildTransitive、buildMultiTargeting 目标 |
让普通构建、传递导入和外层多 TFM 构建走同一协议 |
build/Sparkdo.Runtime.Build.dll |
私有 MSBuild 任务程序集;由目标使用,不是独立业务依赖 |
生成器使用 netstandard2.0 analyzer 资产。本包不提供普通 lib 引用程序集;运行时公共类型请分别引用 Sparkdo.Runtime.Contracts 和/或 Sparkdo.Runtime。
默认接入
应用和 Runtime 包作者应引用 Sparkdo.Runtime.Sdk,或引用一个已经传递携带 SDK 的 Runtime 能力包:
dotnet add package Sparkdo.Runtime.Sdk --version x.y.z
SDK 通过其传递依赖引入 Sparkdo.Runtime.Generators。其 nuspec 中的裸版本 0.0.0 按 NuGet 语义表示 >= 0.0.0,不绑定 SDK 发布版本,也没有最大版本;NuGet 负责根据完整依赖图选择最终版本,packages.lock.json 负责复现该选择。该稳定下界不会自动选择预发布 Generators;需要预发布 Generators 时,消费者必须显式引用所需版本。SDK 不主动选择、锁定、降级或升级 Generators,只对还原结果执行 Protocol 主版本、能力、资产和指纹验证。
兼容/高级入口:直接引用
旧项目、协议调试或需要显式控制低层目标时,可以直接引用该包:
dotnet add package Sparkdo.Runtime.Generators --version x.y.z
或在项目文件中声明:
<ItemGroup>
<PackageReference Include="Sparkdo.Runtime.Generators" Version="x.y.z" />
</ItemGroup>
未通过 SDK bridge 接入时,组合根和作为 RuntimeProject=true 被调用的项目仍必须直接引用该包,目标会验证这一点。为保持旧协议闭包内构建资产和协议版本一致,直接引用路径中的生产者项目也应显式引用它。新项目不应因此重复添加该引用。
兼容/高级协议示例
以下示例展示直接 Generators 协议的低层配置,用于兼容和高级场景;它们不是新应用或新 Runtime 包的默认接入方式。
Runtime 闭包通常由两类项目构成:生产者项目声明工件,最终组合根引用生产者、声明应用身份并接收生成的组合表。
1. 建立一个生产者项目
最小生产者可以先不产出工件,用于验证包、属性和矩阵接线:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<RuntimeSourceId>contoso.orders.catalog</RuntimeSourceId>
<RuntimeSourceVersion>1.0.0</RuntimeSourceVersion>
<RuntimeContractVersion>1.0</RuntimeContractVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Sparkdo.Runtime.Generators" Version="x.y.z" />
</ItemGroup>
</Project>
RuntimeSourceId 和 RuntimeSourceVersion 是稳定的生产来源身份,RuntimeContractVersion 当前必须精确为 1.0。声明 RuntimeSourceId 后,该项目会进入 Producer RuntimeMatrix 模式,即使暂时返回零个工件也会产生可验证的清单和矩阵 witness。
需要提供本地工件时,声明可信根目录并通过 RuntimeGenerateArtifacts 返回 @(RuntimeCatalogItem):
<PropertyGroup>
<RuntimeArtifactsRoot>$([System.IO.Path]::GetFullPath('RuntimeArtifacts', '$(MSBuildProjectDirectory)'))</RuntimeArtifactsRoot>
</PropertyGroup>
<Target Name="CoreRuntimeGenerateArtifacts">
<ItemGroup>
<RuntimeCatalogItem Include="$(RuntimeArtifactsRoot)\runtime\orders\catalog.json">
<RuntimeItemKey>由协议生成的规范键</RuntimeItemKey>
<TargetFramework>$(TargetFramework)</TargetFramework>
<ArtifactKind>Catalog</ArtifactKind>
<CanonicalPath>runtime/orders/catalog.json</CanonicalPath>
<ArtifactPath>$(RuntimeArtifactsRoot)\runtime\orders\catalog.json</ArtifactPath>
<SourceKind>Project</SourceKind>
<SourceId>contoso.orders.catalog</SourceId>
<SourceVersion>1.0.0</SourceVersion>
<ArtifactDigest>工件原始 UTF-8 字节的 64 位小写十六进制摘要</ArtifactDigest>
<ArtifactSchemaVersion>1.0</ArtifactSchemaVersion>
<ProducerArtifactRoot>$(RuntimeArtifactsRoot)</ProducerArtifactRoot>
</RuntimeCatalogItem>
</ItemGroup>
</Target>
示例中的 RuntimeItemKey 和 ArtifactDigest 是占位说明,不能原样复制。它们必须分别是协议六元组的规范编码和基于工件类别、原始 UTF-8 字节计算的协议摘要;占位值会被构建拒绝。ArtifactPath 也不能只是“位于同一目录”,它必须严格等于 ProducerArtifactRoot 加 CanonicalPath 的结果。
2. 建立最终组合根
组合根需要 Runtime 公共类型、生成器包、明确的生产者引用和一个程序集级 RuntimeComposition 属性:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<RuntimeSourceId>contoso.orders.application</RuntimeSourceId>
<RuntimeSourceVersion>1.0.0</RuntimeSourceVersion>
<RuntimeContractVersion>1.0</RuntimeContractVersion>
<SparkdoRuntimeCompositionRequired>true</SparkdoRuntimeCompositionRequired>
<RuntimeArtifactsRoot>$([System.IO.Path]::GetFullPath('RuntimeArtifacts', '$(MSBuildProjectDirectory)'))</RuntimeArtifactsRoot>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Sparkdo.Runtime.Contracts" Version="x.y.z" />
<PackageReference Include="Sparkdo.Runtime" Version="x.y.z" />
<PackageReference Include="Sparkdo.Runtime.Generators" Version="x.y.z" />
<ProjectReference Include="..\Orders.Catalog\Orders.Catalog.csproj"
RuntimeProject="true" />
</ItemGroup>
</Project>
在组合根项目中新增一个 C# 文件:
using Sparkdo.Runtime;
[assembly: RuntimeComposition("contoso.orders")]
组合根必须在当前编译中恰好声明一个该属性,applicationId 必须是规范小写逻辑标识;被引用程序集不得声明它。应用程序集也不能手写 Sparkdo.Runtime.RuntimeCompositionTable,该类型由生成器独占。
RuntimeProject="true" 不是普通项目引用的默认设置。只有确实返回 Sparkdo Runtime contract、catalog envelope 和验证快照的生产者项目才应使用它。
构建输入与产物
项目属性
| 属性 | 何时需要 | 作用 |
|---|---|---|
RuntimeSourceId |
Runtime 生产者和组合根 | 项目的稳定来源身份,并开启 Runtime 收集/矩阵流程 |
RuntimeSourceVersion |
Runtime 生产者和组合根 | 来源版本;参与工件身份校验 |
RuntimeContractVersion |
Runtime 生产者和组合根 | 当前必须为严格版本 1.0 |
SparkdoRuntimeCompositionRequired |
仅最终组合根 | 设为 true 后启用组合根输入、生成器输出与 Composition 矩阵模式 |
RuntimeArtifactsRoot |
直接提供 Project 或 Application 工件时 |
生产工件的可信绝对根目录 |
TargetFramework(s)、RuntimeIdentifier(s) |
多目标或 RID 发布项目 | 定义必须完整验证的 RuntimeMatrix 维度 |
RuntimeIdentifier 为空时表示 portable 构建;中间产物使用独立的 portable 目录段。非空 RID 必须是规范小写标识。
工件收集
导入目标会在 CoreCompile 前执行 SparkdoRuntimeCollect,执行过程如下:
- 调用
RuntimeGenerateArtifacts,它依次运行BeforeRuntimeGenerateArtifacts、CoreRuntimeGenerateArtifacts和AfterRuntimeGenerateArtifacts,并返回@(RuntimeCatalogItem)。 - 合并当前项目工件与标记为
RuntimeProject=true的项目引用闭包。 - 校验每项的身份、路径、schema、原始 UTF-8 字节和
ArtifactDigest,然后写入 canonicalruntime.items.json、独立 stamp 与内容寻址验证快照。 - 将权威清单作为
SparkdoRuntimeInputKind=Manifest的AdditionalFiles注入;组合根还会注入带SparkdoRuntimeInputKind=Artifact和RuntimeItemKey的工件文件。 - 把
SparkdoRuntimeItemsManifestPath、SparkdoRuntimeCompositionRequired、SparkdoRuntimeIdentifier、PublishAot和PublishTrimmed设为编译器可见属性。
中间输出位于:
$(IntermediateOutputPath)/Sparkdo.Runtime/<TFM>/<portable 或 rid-<RID>>/
runtime.items.json
runtime.items.stamp
validation/runtime-validation-v2.index.json
validation/...
不要手工将同一清单或工件再加入 AdditionalFiles。目标发现宿主注入了同一路径时会报错,因为它无法安全合并编译器 metadata。
生成的源代码
生成器只在满足全部条件的最终组合根产出代码:
SparkdoRuntimeCompositionRequired=true。- 当前程序集恰好有一个
[assembly: RuntimeComposition("...")]。 - 清单路径对应恰好一个受标记的 Manifest
AdditionalText。 - 非空组合中的每个清单项都对应唯一、受标记的 Artifact
AdditionalText。 - 工件符合静态组合规则,静态符号能够在当前 compilation 中解析。
成功后生成的提示名为 RuntimeCompositionTable.g.cs,其中定义:
namespace Sparkdo.Runtime;
public sealed class RuntimeCompositionTable : IRuntimeRegistrationTable
{
public static IRuntimeRegistrationTable Instance { get; }
}
实际生成类型同时公开经过验证的 Entries、Contributions、Catalog 和 Environment。生成器会把当前 TargetFramework、RID、PublishAot 和 PublishTrimmed 编入 RuntimeEnvironment。
空闭包也会生成一个空的 RuntimeCompositionTable,因此可以先完成端到端接线,再逐步加入工件。
可静态组合的工件
当前源生成器只接受以下三种工件类别参与静态组合:
| 类别 | 作用 |
|---|---|
Catalog |
提供一个 Owner 或 Contribution 的静态组合条目 |
RegistrationDescriptor |
为 Owner 提供 CapabilityRegistrationBinding 静态注册入口 |
ContributionBinding |
为 Contribution 提供 IContributionCodec 静态 Codec 入口 |
一个工件组必须包含一个 Catalog,并且恰好匹配一个 RegistrationDescriptor 或一个 ContributionBinding。生成器会拒绝重复或冲突的 CapabilityId、ContributionId、全局 BindingId、来源摘要或静态语义;它不会选择“任意一个可用项”。
失效与失败关闭
生成器是增量生成器:每个 Runtime AdditionalText 的原始字节只在对应输入节点失效时读取。但增量执行不改变正确性要求,以下情况都必须重新验证或失败:
- 清单、工件、验证快照、项目资产、项目引用输出或任务程序集发生变化。
- Manifest 与其 compiler-visible 路径不一致,或 Manifest/Artifact 标记与路径、metadata 不匹配。
- 工件原始字节、
ArtifactDigest、RuntimeItemKey、canonical JSON 或来源 witness 不一致。 - Runtime 项目引用返回缺失、重复、路径不匹配或协议版本不兼容的 marker/envelope/snapshot。
- 非完整 TFM/RID 闭包、陈旧矩阵 stamp,或
Pack企图以NoBuild=true复用旧 witness。
收集阶段会删除缺少 manifest 或验证快照的旧 stamp;缓存恢复也会重新校验 manifest、stamp 和快照绑定。组合根在编译前还会再次核验当前工件字节是否仍符合验证快照。错误不会降级为运行时扫描或忽略某个工件。
诊断与排查
| 诊断或现象 | 处理方式 |
|---|---|
SRR1001 |
检查严格 UTF-8、无 BOM/末尾换行的协议文件、ArtifactDigest 和 RuntimeItemKey 是否与实际工件匹配 |
SRR1002 |
清单中出现冲突的 RuntimeItemKey;确认不同来源没有提交同一键的不同工件 |
SRR1003 |
检查组合根是否恰好一个 RuntimeComposition 属性,且引用程序集和源码中没有重复组合根/手写表 |
SRR1004 |
确认项目引用了所需 Runtime 公共类型,且 RegistrationSymbol、CodecSymbol 可在当前 compilation 解析为预期静态类型 |
SRR1005 |
工件不属于 Catalog、RegistrationDescriptor 或 ContributionBinding,或不符合其静态组合规则 |
SRR1006 |
检查直接生成器包引用、RuntimeContractVersion=1.0、RuntimeProject=true 协议、TFM/RID 矩阵与当前 Build witness |
建议先执行:
dotnet build .\YourComposition.csproj --nologo -v:normal
dotnet pack .\YourComposition.csproj --nologo -v:normal
排查构建输入时查看 $(IntermediateOutputPath)\Sparkdo.Runtime。这些文件是构建生成物,不应手工修改;下一次收集或验证会重新检查它们。
接入验收
- 生产者
dotnet build后生成唯一的runtime.items.json和runtime.items.stamp。 - 组合根中
SparkdoRuntimeCollect成功,并为每个RuntimeProject=true引用获得唯一、路径匹配的返回结果。 - 编译时组合根拥有一个 Manifest
AdditionalFiles;非空闭包还拥有与清单逐项匹配的 ArtifactAdditionalFiles。 - 编译器中出现
RuntimeCompositionTable.g.cs,且没有手写同名类型。 - 多 TFM 或多 RID 项目以完整
dotnet build和正常dotnet pack通过矩阵校验。 - 故意修改一个工件字节或删除验证快照时,构建以
SRR诊断失败,而不会静默使用旧清单。
有关私有 MSBuild 任务、清单/stamp 格式和矩阵 witness 的更低层说明,请阅读 Sparkdo.Runtime.Build。
Learn more about Target Frameworks and .NET Standard.
-
.NETStandard 2.0
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Sparkdo.Runtime.Generators:
| Package | Downloads |
|---|---|
|
Sparkdo.Runtime.Sdk
Sparkdo Runtime 的默认构建编排入口。 |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.0.1-preview.7 | 77 | 9/7/2026 |
| 0.0.1-preview.3 | 67 | 8/26/2026 |
| 0.0.1-preview.2 | 72 | 8/25/2026 |
| 0.0.1-preview.1 | 72 | 8/25/2026 |