写点什么

Azure SDK for .NET - 专业代码生成与开发指南

作者:qife122
  • 2025-11-18
    福建
  • 本文字数:3460 字

    阅读完需:约 11 分钟

Azure SDK for .NET

Azure SDK for .NET 是一个功能强大的开发工具包,专门用于构建与 Azure 服务交互的.NET 应用程序。该项目提供了完整的代码生成解决方案,能够从 TypeSpec 或 Swagger 规范自动生成符合 Azure SDK 设计指南的高质量客户端库。

功能特性

核心代码生成能力

  • 多规范支持: 支持 TypeSpec 和 Swagger 两种 API 规范格式

  • 自动客户端生成: 从 API 规范自动生成强类型的客户端代码

  • 协议方法生成: 自动生成基于 HTTP 协议的底层操作方法

  • 便捷方法生成: 提供类型安全的便捷 API 层,提升开发体验

开发体验优化

  • 统一设计指南: 所有生成的代码遵循 Azure SDK for .NET 设计规范

  • 智能序列化: 内置 System.Text.Json 序列化支持

  • 分布式追踪: 自动集成客户端诊断和追踪功能

  • 异步支持: 完整的异步编程模式支持

工程化特性

  • 测试框架集成: 自动生成测试项目和示例代码

  • 包管理: 完整的 NuGet 包生成和版本管理

  • AOT 兼容性: 支持原生 AOT 部署的兼容性测试

  • 多目标框架: 支持.NET Standard 和多个.NET 版本

安装指南

环境要求

  • .NET SDK: 需要.NET 9.0.102 SDK 或更高版本

  • Visual Studio: 2022 版本(Community 或更高),安装.NET 桌面开发工作负载

  • Node.js: 22.x.x 版本(用于代码生成)

  • PowerShell: 7.0 或更高版本

  • Git: 最新版本

项目设置

  1. 克隆仓库并切换到主题分支:


git clone https://github.com/Azure/azure-sdk-for-net.gitcd azure-sdk-for-net
复制代码


  1. 安装必要的工具和依赖:


dotnet restore
复制代码


  1. 构建整个仓库:


dotnet build build.proj
复制代码

构建特定服务

要构建单个服务,使用 scope 参数:


dotnet build build.proj /p:Scope=servicebus
复制代码

使用说明

生成新的 SDK 包

使用 TypeSpec 生成新的数据平面 SDK 包:


pwsh eng/scripts/automation/Invoke-TypeSpecDataPlaneGenerateSDKPackage.ps1 `  -sdkFolder /home/azure-sdk-for-net/sdk/anomalyDetector/Azure.AI.AnomalyDetector `  -typespecSpecDirectory specification/cognitiveservices/AnomalyDetector `  -commit ac8e06a2ed0fc1c54663c98f12c8a073f8026b90
复制代码

生成代码

进入项目 src 目录并生成代码:


cd sdk/<service>/<package>/srcdotnet build /t:GenerateCode
复制代码

基本客户端使用

// 使用Azure Key Credential认证var client = new BasicTypeSpecClient(    new Uri("https://your-endpoint.azure.com"),    new AzureKeyCredential("your-api-key"));
// 调用服务方法var response = await client.SayHiAsync("head-param", "query-param");
复制代码

核心代码

客户端生成核心逻辑

// AzureClientGenerator.cs - 主要的代码生成器[Export(typeof(CodeModelGenerator))][ExportMetadata(GeneratorMetadataName, nameof(AzureClientGenerator))]public class AzureClientGenerator : ScmCodeModelGenerator{    private static AzureClientGenerator? _instance;        public AzureClientGenerator(GeneratorContext context) : base(context)    {        TypeFactory = new AzureTypeFactory();        _instance = this;    }
protected override void Configure() { base.Configure(); // 包含Azure.Core引用 AddMetadataReference(typeof(Response).Assembly.Location); // 添加自定义访问器 AddVisitor(new ModelFactoryRenamerVisitor()); AddVisitor(new NamespaceVisitor()); AddVisitor(new DistributedTracingVisitor()); AddVisitor(new LroVisitor()); }}
复制代码

类型工厂实现

// AzureTypeFactory.cs - 类型创建工厂public class AzureTypeFactory : ScmTypeFactory{    public override IClientResponseApi ClientResponseApi =>         AzureClientResponseProvider.Instance;            public override IHttpResponseApi HttpResponseApi =>         AzureResponseProvider.Instance;            public override IClientPipelineApi ClientPipelineApi =>         HttpPipelineProvider.Instance;
protected internal virtual IReadOnlyList<CSharpProjectWriter.CSProjPackage> AzureDependencyPackages => [ new("Azure.Core", "1.0.0"), new("System.Text.Json", "8.0.0") ];}
复制代码

HTTP 管道构建器

// HttpPipelineProvider.cs - HTTP管道配置public record HttpPipelineProvider : ClientPipelineApi{    public override ValueExpression Create(ValueExpression options, ValueExpression perRetryPolicies)        => Static(typeof(HttpPipelineBuilder))           .Invoke(nameof(HttpPipelineBuilder.Build), [options, perRetryPolicies]);
public override MethodBodyStatement[] CreateMessage( HttpRequestOptionsApi requestOptions, ValueExpression uri, ScopedApi<string> method, ValueExpression requestContent) { return [ Declare("message", Original.Invoke("CreateMessage", requestOptions), out ScopedApi<HttpMessage> message), message.Request().SetMethod(method), message.Request().SetUri(uri), requestContent != Null ? message.Request().Property("Content").Assign(requestContent).Terminate() : MethodBodyStatement.Empty, ApplyPerCallPolicies(message), Return(message) ]; }}
复制代码

响应处理系统

// AzureClientResponseProvider.cs - 客户端响应处理public record AzureClientResponseProvider : ClientResponseApi{    public override CSharpType ClientResponseType => typeof(Response);    public override CSharpType ClientResponseOfTType => typeof(Response<>);        public override ValueExpression CreateAsync(HttpResponseApi response)        => New.Instance(ClientResponseExceptionType, [response]);
public override ValueExpression FromValue(ValueExpression valueExpression, HttpResponseApi response) => Static(ClientResponseType).Invoke(nameof(FromValue), [valueExpression, response]);}
复制代码

分页集合实现

// AzureCollectionResultDefinition.cs - 分页集合处理public class AzureCollectionResultDefinition : CollectionResultDefinition{    protected override string RequestOptionsFieldName => "_context";
public AzureCollectionResultDefinition(ClientProvider client, InputPagingServiceMethod serviceMethod, CSharpType? itemModelType, bool isAsync) : base(client, serviceMethod, itemModelType, isAsync) { _operation = serviceMethod.Operation; _itemModelType = itemModelType; _paging = serviceMethod.Paging; _scopeName = client.GetScopeName(_operation); _getNextResponseMethodName = $"GetNextResponse{(isAsync ? "Async" : "")}"; _isProtocol = true; } // 分页迭代逻辑 public override async IAsyncEnumerable<Page<BinaryData>> AsPages( string continuationToken, int? pageSizeHint) { string nextPage = continuationToken ?? _token; while (true) { Response response = await GetNextResponseAsync(pageSizeHint, nextPage); if (response is null) yield break; var result = (ListWithContinuationTokenResponse)response; var items = result.Things.Select(item => BinaryData.FromObjectAsJson(item)).ToList(); yield return Page<BinaryData>.FromValues(items, nextPage, response); nextPage = result.NextToken; if (nextPage == null) yield break; } }}
复制代码


这些核心组件共同构成了 Azure SDK for .NET 的强大代码生成能力,确保了生成的客户端库具有一致性、高性能和良好的开发体验。更多精彩内容 请关注我的个人公众号 公众号(办公 AI 智能小助手)对网络安全、黑客技术感兴趣的朋友可以关注我的安全公众号(网络安全技术点滴分享)


公众号二维码


办公AI智能小助手


公众号二维码


网络安全技术点滴分享


用户头像

qife122

关注

还未添加个人签名 2021-05-19 加入

还未添加个人简介

评论

发布
暂无评论
Azure SDK for .NET - 专业代码生成与开发指南_.net_qife122_InfoQ写作社区