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: 最新版本
项目设置
- 克隆仓库并切换到主题分支:
git clone https://github.com/Azure/azure-sdk-for-net.git
cd azure-sdk-for-net
- 安装必要的工具和依赖:
dotnet restore
- 构建整个仓库:
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>/src
dotnet 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的强大代码生成能力,确保了生成的客户端库具有一致性、高性能和良好的开发体验。