NexusContract.Hosting 1.0.0-preview.19

This is a prerelease version of NexusContract.Hosting.
The owner has unlisted this package. This could mean that the package is deprecated, has security vulnerabilities or shouldn't be used anymore.
dotnet add package NexusContract.Hosting --version 1.0.0-preview.19
                    
NuGet\Install-Package NexusContract.Hosting -Version 1.0.0-preview.19
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="NexusContract.Hosting" Version="1.0.0-preview.19" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="NexusContract.Hosting" Version="1.0.0-preview.19" />
                    
Directory.Packages.props
<PackageReference Include="NexusContract.Hosting" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add NexusContract.Hosting --version 1.0.0-preview.19
                    
#r "nuget: NexusContract.Hosting, 1.0.0-preview.19"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package NexusContract.Hosting@1.0.0-preview.19
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=NexusContract.Hosting&version=1.0.0-preview.19&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=NexusContract.Hosting&version=1.0.0-preview.19&prerelease
                    
Install as a Cake Tool

NexusContract.Hosting

ASP.NET Core 集成层 | 零代码端点镜像生成 | 基于元数据的自动化

NuGet License

概述

NexusContract.Hosting 是 NexusContract 的 ASP.NET Core 集成层,提供基于元数据的契约端点自动生成能力。它消除了重复的端点映射代码,支持在启动时自动将所有契约生成为可调用的 HTTP 端点,实现真正的零代码端点生成。

核心特性

功能 描述
自动端点镜像 从元数据注册表自动生成端点,无需手动映射
零反射热路径 启动期编译优化,运行时零反射开销
AES256 加密 硬件加速的敏感数据保护(支持 Redis L2 缓存)
启动验证 完整的契约健康检查和诊断报告
路由一致性 与 OpenAPI/Swagger 路由完全对齐

快速开始

安装

dotnet add package NexusContract.Hosting

基本使用

1. 在 Program.cs 中注册服务
using NexusContract.Hosting.Configuration;
using NexusContract.Abstractions.Security;

var builder = WebApplicationBuilder.CreateBuilder(args);

// 注册 NexusContract 服务
builder.Services.AddNexusContracts(options =>
{
    // 扫描包含契约的程序集
    options.ScanAssemblies(typeof(TradeCreateRequest).Assembly);
    
    // 配置选项
    options.Warmup = true;                              // 启用预热(生产推荐)
    options.ThrowOnError = true;                        // 错误时抛异常
    options.ExitOnError = false;                        // 错误时退出(可选)
    options.GenerateJsonReport = true;                  // 生成诊断报告
    options.AppId = "alipay-gateway";                   // 应用 ID
    options.Environment = "Production";                 // 环境标识
});

// 注册安全提供程序(用于敏感数据加密)
var masterKeyBase64 = Environment.GetEnvironmentVariable("NEXUS_MASTER_KEY") 
    ?? throw new InvalidOperationException("NEXUS_MASTER_KEY environment variable not set");
builder.Services.AddSingleton<ISecretProtector>(
    new AesSecurityProvider(masterKeyBase64));

var app = builder.Build();

// 映射契约端点
app.MapNexusEndpoints("/api");

app.Run();
2. 准备契约文件
// Demo.Alipay.Contract/Transactions/TradeCreateRequest.cs
using NexusContract.Abstractions.Attributes;
using NexusContract.Abstractions.Contracts;

[ApiOperation("alipay.trade.create", HttpVerb.POST)]
public class TradeCreateRequest : IApiRequest<TradeCreateResponse>
{
    public string OutTradeNo { get; set; }
    public decimal TotalAmount { get; set; }
    public string Subject { get; set; }
    
    public async Task<TradeCreateResponse> ExecuteAsync(
        IApiExecutor executor, 
        string profileId, 
        CancellationToken cancellationToken = default)
    {
        return await executor.ExecuteAsync<TradeCreateResponse>(
            this, profileId, cancellationToken);
    }
}
3. 验证端点

启动应用后,查看控制台输出:

========================================
NexusContract 服务注册
========================================
📦 发现 20 个契约类型 (来自 1 个程序集)
✅ 契约健康检查通过:20/20 个契约已验证
========================================

[Mirror] 开始注册 20 个端点 (baseRoute: /api)
[Mirror]   ✅ /api/alipay/{profileId}/trade/create
[Mirror]   ✅ /api/alipay/{profileId}/trade/query
[Mirror]   ✅ /api/alipay/{profileId}/trade/refund
...
[Mirror] 端点注册完成

发送请求验证:

curl -X POST http://localhost:5000/api/alipay/default/trade/create \
  -H "Content-Type: application/json" \
  -d '{
    "outTradeNo": "2025011801",
    "totalAmount": 99.99,
    "subject": "Test Order"
  }'

核心模块

1. 配置管理(Configuration)

NexusContractServiceExtensions

负责在启动时注册和验证所有契约。

关键职责:

  • 扫描指定程序集中的契约类型
  • 执行健康检查和元数据验证
  • 预热投影器/水化器
  • 生成诊断报告(JSON 格式)

配置选项:

public class NexusContractOptions
{
    // 预热(启用则在启动时调用所有契约的执行逻辑)
    public bool Warmup { get; set; } = true;

    // 遇到错误时是否抛异常
    public bool ThrowOnError { get; set; } = true;

    // 启动错误是否退出进程
    public bool ExitOnError { get; set; } = false;

    // 是否生成 JSON 诊断报告
    public bool GenerateJsonReport { get; set; } = true;

    // 应用程序 ID(诊断报告中使用)
    public string? AppId { get; set; }

    // 环境名称
    public string? Environment { get; set; }

    // 错误报告保存路径
    public string? ErrorReportPath { get; set; }

    // 自定义命名策略(用于投影器)
    public INamingPolicy? NamingPolicy { get; set; }

    // 加密器(warmup 测试用)
    public IEncryptor? Encryptor { get; set; }

    // 解密器(warmup 测试用)
    public IDecryptor? Decryptor { get; set; }
}
NexusMirrorHostingExtensions

实现零反射的端点映射引擎。

路由模式:

{baseRoute}/{provider}/{profileId}/{operation...}

示例:

  • POST /api/alipay/{profileId}/trade/create
  • GET /api/alipay/{profileId}/trade/query
  • PUT /api/wechat/{profileId}/merchant/modify

工作流程:

启动期(一次性):
  1. 从元数据注册表获取所有契约元数据
  2. 为每个契约类型预编译构造函数(宪法 007 合规)
  3. 缓存方法调用器(MethodInvokerCache)

热路径(零反射):
  1. 从路由参数提取 profileId
  2. 从 HTTP Body 反序列化请求对象
  3. 使用预编译构造函数创建实例(~10-20ns)
  4. 调用 MethodInvokerCache(~100-200ns)
  5. 序列化响应并返回

2. 安全模块(Security)

AesSecurityProvider

高性能的 AES256-CBC 对称加密提供程序。

算法规格:

参数 值
加密算法 AES256-CBC
密钥长度 256 位(32 字节)
初始化向量 随机生成(16 字节)
填充模式 PKCS7
编码格式 Base64
硬件加速 CPU AES-NI 指令集

性能指标:

  • 加密耗时:~5μs(2KB 密钥)
  • 对比网络 IO:1ms Redis 延迟 >> 5μs 加密
  • 热路径无额外开销(宪法 012 合规)

使用示例:

// 初始化加密器
var masterKeyBase64 = Convert.ToBase64String(
    System.Security.Cryptography.RandomNumberGenerator.GetBytes(32));
var provider = new AesSecurityProvider(masterKeyBase64);

// 加密敏感数据
string encrypted = provider.Protect("my-private-key");
// 输出: "ECkR7Yj8n2m...(Base64 格式)"

// 解密数据
string decrypted = provider.Unprotect(encrypted);
// 输出: "my-private-key"

加密格式:

Base64([IV(16字节)][密文])
│
├─ IV:每次加密随机生成(防止模式攻击)
└─ 密文:AES256-CBC 加密结果

安全约束:

  1. 主密钥来源:环境变量 NEXUS_MASTER_KEY(Base64 编码的 32 字节)
  2. 单一标准:所有加密数据统一为 Base64 编码的 [IV+密文]
  3. 密钥升级:通过运维脚本完成数据迁移(代码不参与版本判断)

生成主密钥:

# Linux/macOS
openssl rand -base64 32

# PowerShell
[Convert]::ToBase64String([System.Security.Cryptography.RandomNumberGenerator]::GetBytes(32))
ProtectedPrivateKeyConverter

JSON 序列化时的透明加密/解密转换器。

使用场景:

  • HybridConfigResolver 将配置序列化到 Redis
  • ProviderSettings.PrivateKey 字段保护

工作原理:

// 写入 Redis(序列化):明文 → AES256 加密 → Base64
[JsonPropertyName("privateKey")]
[JsonConverter(typeof(ProtectedPrivateKeyConverter))]
public string PrivateKey { get; set; } = "my-private-key";

// 从 Redis 读取(反序列化):Base64 → AES256 解密 → 明文

安全保障:

位置 存储内容 说明
Redis 密文(Base64) 即使 Redis 泄露也无法直接使用
内存 L1 明文 避免每次签名都解密
传输 TLS 加密 Redis 连接使用 TLS

API 文档

快速注册

// 最简用法
builder.Services.AddNexusContracts(opt => 
    opt.ScanAssemblyContaining<TradeCreateRequest>());

// 完整配置
builder.Services.AddNexusContracts(options =>
{
    options
        .ScanAssemblies(typeof(TradeCreateRequest).Assembly)
        .ScanAssemblies(typeof(MerchantApplyRequest).Assembly);
    
    options.Warmup = true;
    options.AppId = "my-app";
    options.Environment = "Production";
    options.GenerateJsonReport = true;
    options.ErrorReportPath = "logs/contract-errors.json";
});

端点映射

// 使用默认基础路由 "/api"
app.MapNexusEndpoints();

// 使用自定义基础路由
app.MapNexusEndpoints("/v3");

// 多个服务可以使用不同的路由前缀
app.MapNexusEndpoints("/api/v1");
app.MapNexusEndpoints("/open");

使用安全提供程序

// 在 DI 容器中注册
builder.Services.AddSingleton<ISecretProtector>(
    new AesSecurityProvider(masterKeyBase64));

// 在其他服务中注入使用
public class ConfigService
{
    private readonly ISecretProtector _protector;
    
    public ConfigService(ISecretProtector protector)
    {
        _protector = protector;
    }
    
    public void SaveConfig(ProviderSettings settings)
    {
        // 保护敏感字段
        var protected = _protector.Protect(settings.PrivateKey);
        RedisClient.Set("config", protected);
    }
}

诊断报告

自动生成

启动时如果 GenerateJsonReport = true,系统自动生成诊断报告:

{
  "appId": "alipay-gateway",
  "environment": "Production",
  "timestamp": "2025-01-18T08:17:00Z",
  "summary": {
    "totalContracts": 20,
    "successCount": 20,
    "failureCount": 0,
    "criticalErrors": 0
  },
  "contracts": [
    {
      "name": "TradeCreateRequest",
      "operationId": "alipay.trade.create",
      "status": "success"
    }
  ]
}

错误处理

如果发现错误,系统会:

  1. 打印详细的错误信息到控制台
  2. 保存 JSON 报告到 contract-errors.json
  3. 根据 ThrowOnError/ExitOnError 决定是否中止启动
❌ 契约验证失败:
   失败契约数:2
   错误总数:5(3 个致命错误)
   
❌ 系统启动已阻断,请修复上述错误后重试。

与其他模块的关系

架构层次

┌─────────────────────────────────────────┐
│  NexusContract.Hosting (你在这里)        │
│  ASP.NET Core 集成 / 端点镜像 / 安全    │
├─────────────────────────────────────────┤
│  NexusContract.Core                     │
│  执行引擎 / 路由元数据 / 诊断            │
├─────────────────────────────────────────┤
│  NexusContract.Abstractions             │
│  接口 / 属性 / 异常 / 安全契约           │
└─────────────────────────────────────────┘

与 NexusContract.Core 的关系

NexusContract.Hosting 依赖 NexusContract.Core 的核心组件:

组件 用途
INexusEngine 合约执行引擎
NexusContractMetadataRegistry 元数据注册表
ContractStartupHealthCheck 启动检查
EndpointRouteMetadataBuilder 路由元数据生成
MethodInvokerCache 方法调用优化

与 NexusContract.Abstractions 的关系

使用抽象层的接口和属性:

接口/属性 说明
[ApiOperation] 契约标记
IApiRequest<T> 请求契约
ISecretProtector 安全契约
INamingPolicy 命名策略
ContractIncompleteException 契约异常

性能优化

启动期优化

  1. 一次性编译:预编译构造函数(~10-20ns vs 200-500ns)
  2. 方法缓存:MethodInvokerCache 避免反射(~100-200ns vs 500-1000ns)
  3. 路由预生成:所有路由在启动期生成,热路径无计算

热路径优化

// 宪法 007 合规:零反射
var instance = constructorFactory();      // 预编译,~10-20ns

// 宪法 008 合规:直接调用
await MethodInvokerCache.InvokeExecuteAsync(
    engine, requestObj, responseType, providerName, profileId, ct);  // ~100-200ns

// 序列化直接转发
await JsonSerializer.SerializeAsync(context.Response.Body, result);  // 无额外开销

最佳实践

1. 环境变量管理

# .env 或系统环境变量
export NEXUS_MASTER_KEY="base64-encoded-32-bytes"

# appsettings.json
{
  "Logging": {...},
  "NexusContract": {
    "AppId": "my-gateway",
    "Environment": "Production"
  }
}

2. 错误处理

try
{
    builder.Services.AddNexusContracts(options =>
    {
        options.ScanAssemblyContaining<MyContract>();
        options.ThrowOnError = true;  // 生产环境推荐
    });
}
catch (ContractIncompleteException ex)
{
    // 处理契约错误
    logger.LogError($"Contract validation failed: {ex.Message}");
    
    // 可选:保存诊断报告供分析
}

3. 多程序集扫描

builder.Services.AddNexusContracts(options =>
{
    // 分别扫描不同的合约程序集
    options.ScanAssemblyContaining<AlipayContracts>();
    options.ScanAssemblyContaining<WechatContracts>();
    options.ScanAssemblyContaining<UnionpayContracts>();
});

4. 自定义命名策略

public class SnakeCaseNamingPolicy : INamingPolicy
{
    public string GetPropertyName(string clrName)
    {
        // 转换为 snake_case
        return string.Concat(clrName.Select((x, i) => 
            i > 0 && char.IsUpper(x) ? "_" + char.ToLower(x) : x.ToString())).ToLower();
    }
}

builder.Services.AddNexusContracts(options =>
{
    options.NamingPolicy = new SnakeCaseNamingPolicy();
});

故障排查

问题:缺少契约

⚠️ No contract metadata found. Did you forget to call builder.Services.AddNexusContracts()?

解决:确保在 Program.cs 中调用 AddNexusContracts()

问题:端点注册失败

❌ Failed to register TradeCreateRequest: Contract type does not implement IApiRequest<T>

解决:检查契约类是否继承了 IApiRequest<TResponse>

问题:主密钥错误

ArgumentException: Invalid master key: expected Base64-encoded 32-byte key

解决:生成正确的主密钥

openssl rand -base64 32

问题:性能下降

  1. 检查是否在热路径中重复编译构造函数
  2. 验证 MethodInvokerCache 是否正确初始化
  3. 查看是否存在意外的反射调用

宪法依据

本模块遵循以下宪法约束:

宪法 约束 实现
007 零反射热路径 预编译构造函数 + MethodInvokerCache
008 性能隔离 启动期优化 / 热路径无额外开销
011 单一标准加密 AES256-CBC + Base64 编码
012 诊断主权 结构化异常 + 诊断报告

相关资源

许可证

MIT License - 详见 LICENSE


维护者:NexusContract Team
最后更新:2025 年 1 月 18 日

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.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated

v1.0: Contract auto-mirroring from NexusContractMetadataRegistry. Zero-code endpoint generation with physical routing. Removed dependency on FastEndpoints.