NexusContract.Aligner 1.0.0-preview.19

This is a prerelease version of NexusContract.Aligner.
The owner has unlisted this package. This could mean that the package is deprecated, has security vulnerabilities or shouldn't be used anymore.
dotnet tool install --global NexusContract.Aligner --version 1.0.0-preview.19
                    
This package contains a .NET tool you can call from the shell/command line.
dotnet new tool-manifest
                    
if you are setting up this repo
dotnet tool install --local NexusContract.Aligner --version 1.0.0-preview.19
                    
This package contains a .NET tool you can call from the shell/command line.
#tool dotnet:?package=NexusContract.Aligner&version=1.0.0-preview.19&prerelease
                    
nuke :add-package NexusContract.Aligner --version 1.0.0-preview.19
                    

NexusContract.Aligner

OpenAPI → 点号字段(dot-notation)→ C# 契约生成器(简洁、可定制、生产可用)

目标

将 OpenAPI/Swagger 文档的复杂嵌套结构展平为 dot-notation 字段路径,并生成清晰、可编译的 C# Request/Response POCO。目标是生成可直接用于生产、易于维护且便于二次定制的契约代码。

快速开始 ✅

本地生成(开发):

cd src/NexusContract.Aligner
dotnet build
# 运行示例(本地 Swagger 服务)
dotnet run -- -s http://localhost:5000/swagger/v1/swagger.json -o /tmp/gen -n DemoGen

作为已发布工具(示例):

nxc-align -s <source> -o <output> -n <root-namespace> [-m <module>]

CLI 参数

  • -s|--source (string, required): OpenAPI 文档 URL 或本地文件路径
  • -o|--output (string): 输出目录(默认: ./NexusContracts)
  • -n|--namespace (string): 根命名空间(默认: NexusContract.Generated)
  • -m|--module (string): 按 OpenAPI Tag 过滤模块
  • --list (flag): 列出所有可用的模块和接口(不生成代码)
  • --debug (flag): 启用调试模式(详细诊断)

模板与定制

  • 模板文件:src/NexusContract.Aligner/Templates/ContractTemplate.scriban
  • 优先级:工具运行时会优先加载外部 .scriban(csproj 已配置为 CopyToOutputDirectory);若外部模板不可用,工具将回退到内联模板。
  • 修改流程:编辑外部模板 → dotnet build(确保复制)→ 重新运行生成命令。
  • 内联模板仅作为打包工具时的 fallback,建议在开发期间使用外部模板以便热修改与版本控制。

生成代码约定

  • 请求类:{Pascal(OperationId)}Request,实现 IApiRequest<{Type}Response>、IContractValidator、IContractNormalizer(Normalize 仅做标准化,Validate 仅包含物理硬约束)
  • 响应类:{Pascal(OperationId)}Response,纯 POCO,不包含验证逻辑
  • 字段注释:优先使用 OpenAPI 的 description;若无,则使用物理路径(例如 merchantOrderNo)作为注释文本
  • 不生成冗余默认属性(例如 EmitBehavior.Default),仅在必要情况下写出 IsRequired = true

示例:Alipay

生成命令示例:

nxc-align -s http://localhost:5000/swagger/v1/swagger.json -o ./gen -n DemoGen -m alipay

生成样例(截取):

[ApiOperation("alipay.trade.pay", interaction: InteractionKind.RequestResponse)]
public partial class AlipayTradePayRequest : IApiRequest<AlipayTradePayResponse>, IContractValidator, IContractNormalizer
{
    /// <summary>merchantOrderNo</summary>
    [ApiField("merchantOrderNo")]
    public string Merchantorderno { get; set; }

    // ...
}

开发与调试指南

  • 常见入口:
    • SwaggerParser.cs:解析 OpenAPI、展平 Schema、构建 ContractGenerationModel
    • CodeGenerator.cs:加载模板并渲染输出
    • Templates/ContractTemplate.scriban:主模板,直接影响最终代码样式
  • 验证生成:
    1. 修改模板或解析逻辑
    2. dotnet build(确保外部模板被复制)
    3. 运行生成命令,检查 /tmp/gen 输出
  • 常见问题排查:
    • “模板修改无效”:确认外部模板已复制到输出目录(dotnet build)
    • “字段缺失”:检查 SwaggerParser.FlattenSchema 对 $ref 和循环引用的处理
    • “类名包含非法字符”:ContractGenerationModel 将 OperationId 转为 PascalCase(支持 ., _, -)

CI 集成建议

将生成步骤加入 CI(Workflow 或脚本),并在生成后自动提交 src/Generated:

  • 触发器:push/openapi 目录变更或手动 workflow_dispatch
  • 步骤:checkout → setup-dotnet → build/publish工具 → 生成 → commit & push

变更记录(近期重要修复)

  • 支持外部模板复制(csproj 已配置)
  • 修复:使用 Summary(点号)作为业务意图显示而非 Swagger 下划线 operationId
  • 修复:生成类命名(. → PascalCase 转换)
  • 修复:字段注释、Normalize 注释改为 //、响应字段缩进不一致问题

贡献

欢迎 PR 与 Issue。请保证变更包含描述、单元测试(若需要)和更新的 README 或变更日志。

许可证

MIT(详见仓库根目录 LICENSE)


(如需更详细的产品文档或历史文档,请在 PR 中注明,我可以从历史提交中提取并整理精要)

特性

✨ 递归展平算法 - 自动将深层嵌套的 OpenAPI 对象转换为 a.b.c 点号路径
🔄 双源支持 - 支持远程 URL(HTTPS)和本地文件加载
🎯 模块过滤 - 按 OpenAPI Tag 过滤特定模块
🔧 自动代码生成 - 使用 Scriban 模板生成 .NET Standard 2.0 兼容代码
📊 完整类型映射 - OpenAPI 类型自动映射到 C# 类型
🎨 智能文件组织 - 按模块自动创建子文件夹结构

安装

作为 .NET 工具全局安装

dotnet tool install --global NexusContract.Aligner

作为本地工具安装

dotnet tool install NexusContract.Aligner --local

从源码编译

cd src/NexusContract.Aligner
dotnet publish -c Release

快速开始

基本用法

nxc-align \
  -s https://api.example.com/swagger.json \
  -o ./GeneratedContracts \
  -ns MyApp.Contracts

实际例子:宠物店 API

第 1 步:预览所有模块

nxc-align -s https://petstore.swagger.io/v2/swagger.json --list

输出显示有 3 个模块:pet、store、user,共 20 个接口

第 2 步:预览特定模块(如 pet)

nxc-align -s https://petstore.swagger.io/v2/swagger.json --list -m pet

输出显示 pet 模块有 8 个接口,其中 AddANewPetToTheStore 有 7 个字段

第 3 步:生成代码

nxc-align \
  -s https://petstore.swagger.io/v2/swagger.json \
  -o ./PetStore.Contracts \
  -ns "MyPetApp.Contracts" \
  -m pet

生成文件在 ./PetStore.Contracts/Pet/ 目录下

从本地文件生成

nxc-align \
  -s ./local-openapi.json \
  -o ./Contracts \
  -ns "MyCompany.ApiContracts"

查看可用模块和接口

生成前先预览 API 有哪些模块和接口:

# 显示所有模块和接口
nxc-align -s https://api.example.com/swagger.json --list

# 显示特定模块的接口
nxc-align -s https://api.example.com/swagger.json --list -m Transactions

CLI 参数

参数 短形式 类型 必需 说明
--source -s string ✅ OpenAPI 文档源(URL 或本地文件路径)
--output -o string ❌ 输出目录(默认:./NexusContracts)
--namespace -ns string ❌ 生成代码的基础命名空间(默认:NexusContract.Generated)
--module -m string ❌ 模块过滤器(OpenAPI 中的 Tag 名称)
--list flag ❌ 列出所有可用模块和接口(不生成代码)
--debug flag ❌ 启用调试模式(详细诊断)

工作原理

1. 递归展平算法

OpenAPI 中的嵌套结构:

{
  "user": {
    "profile": {
      "name": "string",
      "email": "string"
    },
    "settings": {
      "language": "string"
    }
  }
}

被转换为点号路径:

user.profile.name
user.profile.email
user.settings.language

2. 类型映射

OpenAPI 类型自动映射到 C# 类型:

OpenAPI 类型 C# 类型 备注
number (double) double
number (decimal/null) decimal 默认映射
integer int
integer (int64) long
string string
string (date-time) DateTime
string (uuid) Guid
boolean bool
array List<T> T 为元素类型

3. 代码生成

生成的代码示例(完全符合 .NET Standard 2.0):

// <auto-generated> NXC-Aligner 颗粒度对齐工具生成 </auto-generated>
namespace MyApp.Contracts.Transactions;

using System;
using System.Collections.Generic;
using NexusContract.Abstractions;
using NexusContract.Abstractions.Attributes;

/// <summary>
/// 业务意图: CreateTransaction
/// HTTP POST /api/transactions
/// </summary>
[ApiOperation("CreateTransaction", interaction: InteractionKind.RequestResponse)]
public partial class CreateTransactionRequest : IApiRequest<CreateTransactionResponse>
{
    /// <summary>
    /// [TODO] 用户 ID
    /// [物理路径] user.id
    /// </summary>
    [ApiField("user.id")]
    public string UserId { get; set; }

    /// <summary>
    /// [TODO] 用户名称
    /// [物理路径] user.profile.name
    /// </summary>
    [ApiField("user.profile.name")]
    public string UserProfileName { get; set; }

    public void Validate() 
    {
        // 结构已对齐,请在此处补充物理熔断逻辑
    }
}

/// <summary>
/// 纯 POCO:无接口约束,仅作数据容器
/// </summary>
public partial class CreateTransactionResponse
{
    public string? Code { get; set; }
    public string? Message { get; set; }
}

架构设计

核心模块

NexusContract.Aligner/
├── Models/
│   ├── InteractionKind.cs       # 交互类型枚举
│   ├── FieldMetadata.cs         # 字段元数据
│   └── ContractMetadata.cs      # 契约元数据
├── Parsing/
│   └── SwaggerParser.cs         # OpenAPI 递归解析器
├── Generation/
│   └── CodeGenerator.cs         # 代码生成引擎
├── Commands/
│   └── AlignerCommand.cs        # CLI 命令定义
├── Templates/
│   └── ContractTemplate.scriban # Scriban 模板
└── Program.cs                   # 入口点

SwaggerParser 工作流

OpenAPI Document
    ↓
[远程 URL / 本地文件加载]
    ↓
[递归遍历 OpenApiSchema]
    ↓
[累积 prefix: a → a.b → a.b.c]
    ↓
[提取叶子节点作为 FieldMetadata]
    ↓
[类型映射和文档标注]
    ↓
List<ContractMetadata>

示例场景

场景 0:快速体验(Swagger Petstore)

适合快速上手的完整流程:

# 1. 预览:查看所有模块
nxc-align -s https://petstore.swagger.io/v2/swagger.json --list

# 2. 预览:查看 pet 模块的 8 个接口
nxc-align -s https://petstore.swagger.io/v2/swagger.json --list -m pet

# 3. 生成:仅生成 pet 模块的代码
nxc-align \
  -s https://petstore.swagger.io/v2/swagger.json \
  -o ./PetStore.Contracts \
  -ns "Demo.PetStore.Contracts" \
  -m pet

# 4. 查看生成的文件
ls -la ./PetStore.Contracts/Pet/
cat ./PetStore.Contracts/Pet/AddANewPetToTheStore.cs

生成后的代码结构:

PetStore.Contracts/
├── ContractRegistry.g.cs              # 自动生成的注册表
└── Pet/
    ├── AddANewPetToTheStore.cs        # 7 个字段
    ├── DeletesAPet.cs                 # 0 个字段(仅路径参数)
    ├── FindPetById.cs                 # 0 个字段
    ├── FindsPetsByStatus.cs           # 0 个字段
    ├── FindsPetsByTags.cs             # 0 个字段
    ├── UpdateAnExistingPet.cs         # 7 个字段
    ├── UpdatesAPetInTheStoreWithFormData.cs  # 2 个字段
    └── UploadsAnImage.cs              # 2 个字段

场景 1:Alipay 三方网关

nxc-align \
  -s "https://opendocs.alipay.com/open-api/transaction-creation" \
  -o "./Alipay.Contracts" \
  -ns "MyPay.Alipay.Contracts" \
  -m "Transactions"

生成文件结构:

Alipay.Contracts/
└── Transactions/
    ├── CreateTransactionRequest.cs
    ├── QueryTransactionRequest.cs
    └── RefundTransactionRequest.cs

场景 2:微信支付申请

nxc-align \
  -s "./wechat-applyment.json" \
  -o "./WeChat.Contracts" \
  -ns "MyPay.WeChat.Contracts" \
  -m "Applyment"

高级用法

结合 CI/CD 流程

# .github/workflows/generate-contracts.yml
name: Generate Contracts

on:
  workflow_dispatch:
  push:
    paths:
      - 'openapi/**'

jobs:
  generate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-dotnet@v3
        with:
          dotnet-version: '10.0.x'
      
      - name: Generate Contracts
        run: |
          dotnet tool install --global NexusContract.Aligner
          nxc-align -s ./openapi/main.json -o ./src/Generated -ns "MyApp.Generated"
      
      - name: Commit changes
        run: |
          git config user.name "bot"
          git add src/Generated/
          git commit -m "chore: update generated contracts" || true
          git push

与 Swagger UI 集成

生成的契约代码可直接用于 Swagger/Swashbuckle 属性标记:

[HttpPost("/api/transactions")]
[SwaggerOperation("CreateTransaction")]
public IActionResult CreateTransaction([FromBody] CreateTransactionRequest request)
{
    request.Validate();
    // 业务逻辑...
}

配置选项

环境变量

export NXC_ALIGN_DEFAULT_NS="MyCompany.Contracts"
export NXC_ALIGN_OUTPUT_DIR="./GeneratedContracts"
nxc-align -s https://api.example.com/swagger.json

故障排除

问题 1:返回对象为空(0 个字段)

某个接口生成的 Request 类没有任何字段

原因与解决方案:

  • 这是正常现象!某些接口(如 GET /pet/{id})只有路径参数,没有请求体
  • 用 --list 预览可以看到每个接口的字段数:
nxc-align -s https://petstore.swagger.io/v2/swagger.json --list -m pet
# 可看到 FindPetById 字段数为 0(仅有路径参数 {petId})
# 而 AddANewPetToTheStore 字段数为 7(有请求体)

问题 2:无法加载远程 URL

error: Failed to parse OpenAPI from https://...

解决方案:

  • 检查 URL 是否可访问
  • 验证 HTTPS 证书(如适用)
  • 使用 --debug 标志查看详细错误

问题 3:本地文件找不到

error: OpenAPI file not found: ./swagger.json

解决方案:

  • 确保文件路径正确
  • 使用绝对路径或正确的相对路径
  • 检查文件权限

问题 4:模块过滤无结果

解决方案:

  • 验证 OpenAPI 中的 Tag 名称(区分大小写)
  • 用 --list 查看所有可用模块名

性能考虑

  • 递归深度:通常限制在 10+ 层嵌套(大多数 API 不会超过 5 层)
  • 处理时间:单个 OpenAPI 文档通常在 500ms 内完成
  • 内存占用:约 50-100MB(取决于文档大小)

兼容性

  • ✅ .NET 10(工具本身)
  • ✅ .NET Standard 2.0(生成代码)
  • ✅ OpenAPI 3.0 及更早版本
  • ✅ Swagger 2.0 (via Microsoft.OpenApi.Readers)

扩展性

自定义模板

编辑 Templates/ContractTemplate.scriban 以自定义生成的代码:

// 添加自定义属性
[CustomAttribute("{{ operation_id }}")]
public partial class {{ class_name }}Request : IApiRequest<{{ class_name }}Response>
{
    // ...自定义内容
}

自定义类型映射

修改 SwaggerParser.MapDataType() 方法以添加新的类型映射。

贡献指南

欢迎提交 Issue 和 Pull Request!请确保:

  1. 代码遵循项目风格指南
  2. 添加适当的单元测试
  3. 更新文档
  4. 提供有意义的提交消息

许可证

MIT License - 详见 LICENSE 文件

相关资源

支持


详细文档(已合并) 🗂️

为便于使用与维护,仓库内的 Aligner 相关文档已合并到本 README。以下为来自 FINAL_SUMMARY.md、GENERATION_RULES.md、IMPLEMENTATION_SUMMARY.md、INTEGRATION.md、OPTIMIZATION_APPROACH.md 和 QUICKSTART.md 的精要汇总(保留原文要点,去除重复与冗长描述):

项目状态与目标 ✅

  • 目标:将 OpenAPI/Swagger 文档自动转换为“统一用点(dot-notation)”的 C# 契约代码,生成高质量、运行期零反射的契约类。
  • 目前:Aligner 已完成递归展平、模板化代码生成、ContractRegistry 输出、CLI 工具,以及性能/可维护性优化(生产就绪)。

生成规范精要(来自 GENERATION_RULES) 🔧

  • Validate() 仅包含物理硬约束(NexusGuard.EnsurePhysicalAddress),留出 [AI-HINT] 扩展点用于业务软约束。
  • Normalize() 仅做标准化(String.Trim 等),不得写入业务状态或元数据。
  • Response 类为纯 POCO,不实现接口或包含验证逻辑。
  • SchemaVersion 在 Attribute 中默认为 1,生成代码不显式写出 SchemaVersion 字段。
  • 生成文件组织:按 OpenAPI Tag 建目录,文件名为 OperationId 的 PascalCase + Request/Response。

核心实现概览(来自 IMPLEMENTATION_SUMMARY) ⚙️

  • Models:ContractMetadata, FieldMetadata, InteractionKind。
  • Parsing:SwaggerParser 实现递归展平、类型映射(OpenAPI → C#)。
  • Generation:CodeGenerator 加载 Scriban 模板渲染类文件并生成 ContractRegistry.g.cs。
  • CLI:AlignerCommand(Spectre.Console.Cli)支持 -s/--source, -o/--output, -ns/--namespace, -m/--module 等参数。

集成与运行(来自 INTEGRATION / QUICKSTART) 🚀

  • 生成后:将输出目录加入工程并调用 services.RegisterGeneratedContracts()。
  • 快速命令:
nxc-align -s <OpenAPI_URL_or_file> -o ./Contracts -ns "MyApp.Contracts" -m Transactions
  • CI:建议在生成后校验并提交 src/Generated,将生成步骤纳入 CI(避免手工 drift)。

优化要点(来自 OPTIMIZATION_APPROACH) ⚡

  • NexusGuard.EnsurePhysicalAddress 的调用被蚀刻到 Validate():零反射、可内联、几乎无分配(对 2C2G 环境友好)。
  • 通过 Expression Tree / 编译时生成实现运行期零反射;建议在 Core 启动时进行预热以消除首次请求的 JIT 抖动。

使用与调试建议

  • 本地构建:dotnet build src/NexusContract.Aligner
  • 运行(开发):dotnet run -- -s <source> -o <output> -ns "DemoApp.Contracts"
  • 模板修改:编辑 Templates/ContractTemplate.scriban 并重新运行生成。

注:原始的长文档已并入本 README,仓库中相关 Markdown 文件已替换为指向本 README 的删除说明(便于历史记录与审计)。如需查看合并前的原文,请查阅提交历史。

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

Version Downloads Last Updated