dotnet-native-aot

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

dotnet-native-aot

dotnet-native-aot

Full Native AOT compilation pipeline for .NET 8+ applications:
PublishAot
configuration, ILLink descriptor XML for type preservation, reflection-free coding patterns, P/Invoke considerations, binary size optimization, self-contained deployment with
runtime-deps
base images, and diagnostic analyzers (
EnableAotAnalyzer
/
EnableTrimAnalyzer
).
Version assumptions: .NET 8.0+ baseline. Native AOT for ASP.NET Core Minimal APIs and console apps shipped in .NET 8. .NET 9 improved trimming warnings and library compat. .NET 10 enhanced request delegate generator and expanded Minimal API AOT support.
适用于.NET 8+应用的完整Native AOT编译流程:包含
PublishAot
配置、用于类型保留的ILLink描述符XML、无反射编码模式、P/Invoke调用注意事项、二进制体积优化、基于
runtime-deps
基础镜像的自包含部署,以及诊断分析器(
EnableAotAnalyzer
/
EnableTrimAnalyzer
)。
版本说明:以.NET 8.0+为基础版本。ASP.NET Core Minimal API和控制台应用的Native AOT功能在.NET 8中正式推出。.NET 9优化了裁剪警告和库兼容性。.NET 10增强了请求委托生成器,并扩展了Minimal API的AOT支持。

Scope

适用范围

  • PublishAot MSBuild configuration (apps vs libraries)
  • Diagnostic analyzers (EnableAotAnalyzer, EnableTrimAnalyzer)
  • ILLink descriptor XML for type preservation
  • Reflection-free coding patterns
  • P/Invoke with LibraryImport source generation
  • Binary size optimization and self-contained deployment
  • ASP.NET Core Native AOT (Minimal APIs, CreateSlimBuilder)
  • 应用与类库的PublishAot MSBuild配置
  • 诊断分析器(EnableAotAnalyzer、EnableTrimAnalyzer)
  • 用于类型保留的ILLink描述符XML
  • 无反射编码模式
  • 基于LibraryImport源代码生成的P/Invoke调用
  • 二进制体积优化与自包含部署
  • ASP.NET Core Native AOT(Minimal APIs、CreateSlimBuilder)

Out of scope

不适用范围

  • MAUI iOS/Mac Catalyst AOT pipeline -- see [skill:dotnet-maui-aot]
  • AOT-first design patterns (source gen, DI, serialization) -- see [skill:dotnet-aot-architecture]
  • Trim-safe library authoring -- see [skill:dotnet-trimming]
  • WASM AOT for Blazor/Uno -- see [skill:dotnet-aot-wasm]
  • Source generator authoring (Roslyn API) -- see [skill:dotnet-csharp-source-generators]
  • DI container patterns -- see [skill:dotnet-csharp-dependency-injection]
  • Serialization depth -- see [skill:dotnet-serialization]
  • Container deployment orchestration -- see [skill:dotnet-containers]
Cross-references: [skill:dotnet-aot-architecture] for AOT-first design patterns, [skill:dotnet-trimming] for trim-safe library authoring, [skill:dotnet-aot-wasm] for WebAssembly AOT, [skill:dotnet-maui-aot] for MAUI-specific AOT, [skill:dotnet-containers] for
runtime-deps
base images, [skill:dotnet-serialization] for AOT-safe serialization, [skill:dotnet-csharp-source-generators] for source gen as AOT enabler, [skill:dotnet-csharp-dependency-injection] for AOT-safe DI, [skill:dotnet-native-interop] for general P/Invoke patterns and cross-platform library resolution.

  • MAUI iOS/Mac Catalyst AOT流程——详见[skill:dotnet-maui-aot]
  • AOT优先设计模式(源代码生成、依赖注入、序列化)——详见[skill:dotnet-aot-architecture]
  • 支持裁剪的类库开发——详见[skill:dotnet-trimming]
  • Blazor/Uno的WASM AOT——详见[skill:dotnet-aot-wasm]
  • 源代码生成器开发(Roslyn API)——详见[skill:dotnet-csharp-source-generators]
  • 依赖注入容器模式——详见[skill:dotnet-csharp-dependency-injection]
  • 序列化深度——详见[skill:dotnet-serialization]
  • 容器部署编排——详见[skill:dotnet-containers]
交叉参考:AOT优先设计模式请见[skill:dotnet-aot-architecture],支持裁剪的类库开发请见[skill:dotnet-trimming],WebAssembly AOT请见[skill:dotnet-aot-wasm],MAUI专属AOT请见[skill:dotnet-maui-aot],
runtime-deps
基础镜像相关请见[skill:dotnet-containers],AOT安全序列化请见[skill:dotnet-serialization],作为AOT实现方式的源代码生成请见[skill:dotnet-csharp-source-generators],AOT安全依赖注入请见[skill:dotnet-csharp-dependency-injection],通用P/Invoke模式与跨平台库解析请见[skill:dotnet-native-interop]。

PublishAot Configuration

PublishAot配置

Enabling Native AOT

启用Native AOT

xml
<!-- App .csproj -->
<PropertyGroup>
  <PublishAot>true</PublishAot>
</PropertyGroup>
bash
undefined
xml
<!-- 应用项目.csproj -->
<PropertyGroup>
  <PublishAot>true</PublishAot>
</PropertyGroup>
bash
undefined

Publish as Native AOT

以Native AOT方式发布

dotnet publish -c Release -r linux-x64
dotnet publish -c Release -r linux-x64

Publish for specific targets

针对特定目标平台发布

dotnet publish -c Release -r win-x64 dotnet publish -c Release -r osx-arm64
undefined
dotnet publish -c Release -r win-x64 dotnet publish -c Release -r osx-arm64
undefined

MSBuild Properties: Apps vs Libraries

MSBuild属性:应用 vs 类库

Apps and libraries use different MSBuild properties. Do not mix them.
For applications (console apps, ASP.NET Core Minimal APIs):
xml
<PropertyGroup>
  <!-- Enable Native AOT compilation on publish -->
  <PublishAot>true</PublishAot>

  <!-- Enable analyzers during development (not just publish) -->
  <EnableAotAnalyzer>true</EnableAotAnalyzer>
  <EnableTrimAnalyzer>true</EnableTrimAnalyzer>
</PropertyGroup>
For libraries (NuGet packages, shared class libraries):
xml
<PropertyGroup>
  <!-- Declare the library is AOT-compatible (auto-enables analyzers) -->
  <IsAotCompatible>true</IsAotCompatible>
  <!-- Declare the library is trim-safe (auto-enables trim analyzer) -->
  <IsTrimmable>true</IsTrimmable>
</PropertyGroup>
IsAotCompatible
and
IsTrimmable
automatically enable the AOT and trim analyzers respectively. Do not also set
PublishAot
in library projects -- libraries are not published as standalone executables.

应用和类库使用不同的MSBuild属性,请勿混用。
针对应用(控制台应用、ASP.NET Core Minimal API):
xml
<PropertyGroup>
  <!-- 发布时启用Native AOT编译 -->
  <PublishAot>true</PublishAot>

  <!-- 在开发阶段启用分析器(而非仅发布时) -->
  <EnableAotAnalyzer>true</EnableAotAnalyzer>
  <EnableTrimAnalyzer>true</EnableTrimAnalyzer>
</PropertyGroup>
针对类库(NuGet包、共享类库):
xml
<PropertyGroup>
  <!-- 声明类库兼容AOT(自动启用AOT分析器) -->
  <IsAotCompatible>true</IsAotCompatible>
  <!-- 声明类库支持裁剪(自动启用裁剪分析器) -->
  <IsTrimmable>true</IsTrimmable>
</PropertyGroup>
IsAotCompatible
IsTrimmable
会分别自动启用AOT和裁剪分析器。请勿在类库项目中设置
PublishAot
——类库不会被发布为独立可执行文件。

Diagnostic Analyzers

诊断分析器

Enable AOT and trim analyzers during development to catch issues before publishing:
xml
<PropertyGroup>
  <EnableAotAnalyzer>true</EnableAotAnalyzer>
  <EnableTrimAnalyzer>true</EnableTrimAnalyzer>
</PropertyGroup>
在开发阶段启用AOT和裁剪分析器,以便在发布前发现问题:
xml
<PropertyGroup>
  <EnableAotAnalyzer>true</EnableAotAnalyzer>
  <EnableTrimAnalyzer>true</EnableTrimAnalyzer>
</PropertyGroup>

Analysis Without Publishing

无需发布即可执行分析

Run analysis during
dotnet build
without a full publish:
bash
undefined
dotnet build
过程中执行分析,无需完整发布:
bash
undefined

Analyze AOT compatibility without publishing

不发布即可分析AOT兼容性

dotnet build /p:EnableAotAnalyzer=true /p:EnableTrimAnalyzer=true
dotnet build /p:EnableAotAnalyzer=true /p:EnableTrimAnalyzer=true

See per-occurrence warnings (not grouped by assembly)

查看每个实例的警告(不按程序集分组)

dotnet build /p:EnableAotAnalyzer=true /p:EnableTrimAnalyzer=true /p:TrimmerSingleWarn=false

This reports IL2xxx (trim) and IL3xxx (AOT) warnings without producing a native binary, enabling fast feedback during development.
dotnet build /p:EnableAotAnalyzer=true /p:EnableTrimAnalyzer=true /p:TrimmerSingleWarn=false

此命令会报告IL2xxx(裁剪)和IL3xxx(AOT)警告,无需生成原生二进制文件,可在开发过程中快速获取反馈。

Common Diagnostic Codes

常见诊断代码

CodeCategoryMeaning
IL2026TrimMember has
[RequiresUnreferencedCode]
-- may break after trimming
IL2046TrimTrim attribute mismatch between base/derived types
IL2057-IL2072TrimVarious reflection usage that the trimmer cannot analyze
IL3050AOTMember has
[RequiresDynamicCode]
-- generates code at runtime
IL3051AOT
[RequiresDynamicCode]
attribute mismatch

代码类别含义
IL2026裁剪成员包含
[RequiresUnreferencedCode]
特性——裁剪后可能失效
IL2046裁剪基类/派生类之间的裁剪特性不匹配
IL2057-IL2072裁剪裁剪器无法分析的各类反射用法
IL3050AOT成员包含
[RequiresDynamicCode]
特性——会在运行时生成代码
IL3051AOT
[RequiresDynamicCode]
特性不匹配

ILLink Descriptors for Type Preservation

用于类型保留的ILLink描述符

When code uses reflection that the trimmer cannot statically analyze, use ILLink descriptor XML to preserve types. Do not use legacy RD.xml -- it is a .NET Native/UWP format that is silently ignored by modern .NET AOT.
当代码使用裁剪器无法静态分析的反射时,可使用ILLink描述符XML来保留类型。请勿使用旧版RD.xml——这是.NET Native/UWP格式,现代.NET AOT会自动忽略它。

ILLink Descriptor XML

ILLink描述符XML

xml
<!-- ILLink.Descriptors.xml -->
<linker>
  <!-- Preserve all public members of a type -->
  <assembly fullname="MyApp">
    <type fullname="MyApp.Models.LegacyConfig" preserve="all" />
    <type fullname="MyApp.Services.PluginLoader">
      <method name="LoadPlugin" />
    </type>
  </assembly>

  <!-- Preserve an entire external assembly -->
  <assembly fullname="IncompatibleLibrary" preserve="all" />
</linker>
xml
<!-- Register in .csproj -->
<ItemGroup>
  <TrimmerRootDescriptor Include="ILLink.Descriptors.xml" />
</ItemGroup>
xml
<!-- ILLink.Descriptors.xml -->
<linker>
  <!-- 保留某个类型的所有公共成员 -->
  <assembly fullname="MyApp">
    <type fullname="MyApp.Models.LegacyConfig" preserve="all" />
    <type fullname="MyApp.Services.PluginLoader">
      <method name="LoadPlugin" />
    </type>
  </assembly>

  <!-- 保留整个外部程序集 -->
  <assembly fullname="IncompatibleLibrary" preserve="all" />
</linker>
xml
<!-- 在.csproj中注册 -->
<ItemGroup>
  <TrimmerRootDescriptor Include="ILLink.Descriptors.xml" />
</ItemGroup>

[DynamicDependency]
Attribute

[DynamicDependency]
特性

For targeted preservation in code (preferred over ILLink XML for small, localized cases):
csharp
using System.Diagnostics.CodeAnalysis;

// Preserve a specific method
[DynamicDependency(nameof(LegacyConfig.Initialize), typeof(LegacyConfig))]
public void ConfigureApp() { /* ... */ }

// Preserve all public members
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(PluginBase))]
public void LoadPlugins() { /* ... */ }
针对代码中的目标保留场景(对于小型本地化场景,优先于ILLink XML):
csharp
using System.Diagnostics.CodeAnalysis;

// 保留特定方法
[DynamicDependency(nameof(LegacyConfig.Initialize), typeof(LegacyConfig))]
public void ConfigureApp() { /* ... */ }

// 保留所有公共成员
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(PluginBase))]
public void LoadPlugins() { /* ... */ }

When to Use Which

适用场景对比

ScenarioApproach
One or two methods/types
[DynamicDependency]
attribute
Entire assembly or many typesILLink descriptor XML
Third-party library not AOT-safeILLink descriptor XML or
<TrimmerRootAssembly>
Your own code with analyzed reflectionRefactor to source generators (best long-term)

场景实现方式
单个或两个方法/类型
[DynamicDependency]
特性
整个程序集或多个类型ILLink描述符XML
不兼容AOT的第三方库ILLink描述符XML或
<TrimmerRootAssembly>
自身代码中包含可分析的反射重构为源代码生成(长期最优方案)

Reflection-Free Patterns

无反射模式

Native AOT works best with code that avoids runtime reflection entirely. Replace reflection patterns with compile-time alternatives.
Reflection PatternAOT-Safe Replacement
Activator.CreateInstance<T>()
Factory method or explicit
new T()
Type.GetProperties()
for mapping
Mapperly source generator or manual mapping
Assembly.GetTypes()
for DI scanning
Explicit
services.AddScoped<T>()
JsonSerializer.Deserialize<T>(json)
JsonSerializer.Deserialize(json, Context.Default.T)
MethodInfo.Invoke()
for dispatch
switch
on type or interface dispatch
See [skill:dotnet-aot-architecture] for comprehensive AOT-first design patterns.

Native AOT在完全避免运行时反射的代码中表现最佳。请使用编译时替代方案替换反射模式。
反射模式AOT安全替代方案
Activator.CreateInstance<T>()
工厂方法或显式
new T()
Type.GetProperties()
用于映射
Mapperly源代码生成器或手动映射
Assembly.GetTypes()
用于依赖注入扫描
显式
services.AddScoped<T>()
JsonSerializer.Deserialize<T>(json)
JsonSerializer.Deserialize(json, Context.Default.T)
MethodInfo.Invoke()
用于调度
基于类型的
switch
或接口调度
完整的AOT优先设计模式请见[skill:dotnet-aot-architecture]。

P/Invoke Considerations

P/Invoke调用注意事项

P/Invoke (platform invoke) calls to native libraries generally work with Native AOT, but require attention:
对原生库的P/Invoke(平台调用)通常可在Native AOT中正常工作,但需要注意以下几点:

Direct P/Invoke (Preferred)

直接P/Invoke(推荐)

csharp
// Direct P/Invoke -- AOT-compatible, no runtime marshalling overhead
[LibraryImport("libsqlite3", EntryPoint = "sqlite3_open")]
internal static partial int Sqlite3Open(
    [MarshalAs(UnmanagedType.LPStr)] string filename,
    out nint db);
Use
[LibraryImport]
(.NET 7+) instead of
[DllImport]
-- it generates marshalling code at compile time via source generators, making it fully AOT-compatible.
csharp
// 直接P/Invoke——兼容AOT,无运行时封送开销
[LibraryImport("libsqlite3", EntryPoint = "sqlite3_open")]
internal static partial int Sqlite3Open(
    [MarshalAs(UnmanagedType.LPStr)] string filename,
    out nint db);
请使用
[LibraryImport]
(.NET 7+)替代
[DllImport]
——它通过源代码生成器在编译时生成封送代码,完全兼容AOT。

DllImport vs LibraryImport

DllImport vs LibraryImport

AttributeAOT CompatibilityMarshalling
[DllImport]
Partial -- some marshalling requires runtime codegenRuntime marshalling
[LibraryImport]
Full -- compile-time source genCompile-time marshalling
csharp
// Migrate from DllImport to LibraryImport
// Before:
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool CloseHandle(IntPtr hObject);

// After:
[LibraryImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static partial bool CloseHandle(IntPtr hObject);
特性AOT兼容性封送方式
[DllImport]
部分兼容——部分封送需要运行时代码生成运行时封送
[LibraryImport]
完全兼容——编译时源代码生成编译时封送
csharp
// 从DllImport迁移到LibraryImport
// 迁移前:
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool CloseHandle(IntPtr hObject);

// 迁移后:
[LibraryImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static partial bool CloseHandle(IntPtr hObject);

Native Library Deployment

原生库部署

When publishing as Native AOT, native libraries (
.so
,
.dylib
,
.dll
) must be alongside the binary:
xml
<ItemGroup>
  <!-- Include native library in publish output -->
  <NativeLibrary Include="libs/libcustom.so" />
</ItemGroup>

以Native AOT方式发布时,原生库(
.so
.dylib
.dll
)必须与二进制文件放在同一目录下:
xml
<ItemGroup>
  <!-- 将原生库包含在发布输出中 -->
  <NativeLibrary Include="libs/libcustom.so" />
</ItemGroup>

Size Optimization

体积优化

Binary Size Reduction Options

二进制体积缩减选项

xml
<PropertyGroup>
  <PublishAot>true</PublishAot>

  <!-- Strip debug symbols (significant size reduction) -->
  <StripSymbols>true</StripSymbols>

  <!-- Optimize for size over speed -->
  <OptimizationPreference>Size</OptimizationPreference>

  <!-- Enable invariant globalization (removes ICU data) -->
  <InvariantGlobalization>true</InvariantGlobalization>

  <!-- Remove stack trace strings (reduces size, harder debugging) -->
  <StackTraceSupport>false</StackTraceSupport>

  <!-- Remove EventSource/EventPipe (if not using diagnostics) -->
  <EventSourceSupport>false</EventSourceSupport>
</PropertyGroup>
xml
<PropertyGroup>
  <PublishAot>true</PublishAot>

  <!-- 剥离调试符号(大幅缩减体积) -->
  <StripSymbols>true</StripSymbols>

  <!-- 优先优化体积而非速度 -->
  <OptimizationPreference>Size</OptimizationPreference>

  <!-- 启用不变全球化(移除ICU数据) -->
  <InvariantGlobalization>true</InvariantGlobalization>

  <!-- 移除堆栈跟踪字符串(缩减体积,但调试难度增加) -->
  <StackTraceSupport>false</StackTraceSupport>

  <!-- 移除EventSource/EventPipe(如果不使用诊断功能) -->
  <EventSourceSupport>false</EventSourceSupport>
</PropertyGroup>

Typical Binary Sizes

典型二进制体积

ConfigurationConsole AppASP.NET Minimal API
Default AOT~10-15 MB~15-25 MB
+ StripSymbols~8-12 MB~12-20 MB
+ Size optimization~6-10 MB~10-18 MB
+ InvariantGlobalization~4-8 MB~8-15 MB
配置控制台应用ASP.NET Core Minimal API
默认AOT~10-15 MB~15-25 MB
+ 剥离符号~8-12 MB~12-20 MB
+ 体积优化~6-10 MB~10-18 MB
+ 不变全球化~4-8 MB~8-15 MB

Size Analysis

体积分析

bash
undefined
bash
undefined

Analyze what contributes to binary size

分析二进制体积的构成

dotnet publish -c Release -r linux-x64 /p:PublishAot=true
dotnet publish -c Release -r linux-x64 /p:PublishAot=true

Use sizoscope (community tool) for detailed size analysis

使用社区工具sizoscope进行详细体积分析


---

---

Self-Contained Deployment with runtime-deps

自包含部署与runtime-deps

Native AOT produces self-contained binaries that include the .NET runtime. Use the
runtime-deps
base image for minimal container size since the runtime is already embedded in the binary.
dockerfile
undefined
Native AOT生成包含.NET运行时的自包含二进制文件。使用
runtime-deps
基础镜像可实现最小容器体积,因为运行时已嵌入到二进制文件中。
dockerfile
undefined

Build stage

构建阶段

FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build WORKDIR /src COPY . . RUN dotnet publish -c Release -r linux-x64 -o /app/publish
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build WORKDIR /src COPY . . RUN dotnet publish -c Release -r linux-x64 -o /app/publish

Runtime stage -- use runtime-deps, not aspnet or runtime

运行阶段——使用runtime-deps,而非aspnet或runtime

FROM mcr.microsoft.com/dotnet/runtime-deps:10.0-noble-chiseled AS runtime WORKDIR /app COPY --from=build /app/publish . ENTRYPOINT ["./MyApp"]

The `runtime-deps` image contains only OS-level dependencies (libc, OpenSSL, etc.) -- no .NET runtime. This is the smallest possible base image for AOT-published apps (~30 MB). See [skill:dotnet-containers] for full container patterns.

---
FROM mcr.microsoft.com/dotnet/runtime-deps:10.0-noble-chiseled AS runtime WORKDIR /app COPY --from=build /app/publish . ENTRYPOINT ["./MyApp"]

`runtime-deps`镜像仅包含操作系统级依赖(libc、OpenSSL等)——不包含.NET运行时。这是AOT发布应用的最小基础镜像(约30 MB)。完整的容器模式请见[skill:dotnet-containers]。

---

ASP.NET Core Native AOT

ASP.NET Core Native AOT

Minimal API Support (.NET 8+)

Minimal API支持(.NET 8+)

ASP.NET Core Minimal APIs support Native AOT. MVC controllers are not AOT-compatible (they rely on reflection for model binding, filters, and routing).
csharp
var builder = WebApplication.CreateSlimBuilder(args);

// Use source-generated JSON context
builder.Services.ConfigureHttpJsonOptions(options =>
{
    options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonContext.Default);
});

var app = builder.Build();

app.MapGet("/api/products/{id}", (int id) =>
    Results.Ok(new Product(id, "Widget")));

app.Run();

[JsonSerializable(typeof(Product))]
internal partial class AppJsonContext : JsonSerializerContext { }

record Product(int Id, string Name);
ASP.NET Core Minimal API支持Native AOT。MVC控制器不兼容AOT(它们依赖反射进行模型绑定、过滤器和路由)。
csharp
var builder = WebApplication.CreateSlimBuilder(args);

// 使用源代码生成的JSON上下文
builder.Services.ConfigureHttpJsonOptions(options =>
{
    options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonContext.Default);
});

var app = builder.Build();

app.MapGet("/api/products/{id}", (int id) =>
    Results.Ok(new Product(id, "Widget")));

app.Run();

[JsonSerializable(typeof(Product))]
internal partial class AppJsonContext : JsonSerializerContext { }

record Product(int Id, string Name);

CreateSlimBuilder vs CreateBuilder

CreateSlimBuilder vs CreateBuilder

MethodAOT SupportIncludes
WebApplication.CreateSlimBuilder()
FullMinimal services, no MVC, no Razor
WebApplication.CreateBuilder()
PartialFull feature set, some features need reflection
Use
CreateSlimBuilder
for Native AOT applications. It excludes features that require runtime code generation.
方法AOT支持包含内容
WebApplication.CreateSlimBuilder()
完全支持最小化服务,无MVC,无Razor
WebApplication.CreateBuilder()
部分支持完整功能集,部分功能依赖反射
请为Native AOT应用使用
CreateSlimBuilder
。它会排除需要运行时代码生成的功能。

.NET 10 ASP.NET Core AOT Improvements

.NET 10 ASP.NET Core AOT改进

.NET 10 brings improvements across the ASP.NET Core and runtime Native AOT stack. Target
net10.0
to benefit automatically.
xml
<PropertyGroup>
  <TargetFramework>net10.0</TargetFramework>
  <PublishAot>true</PublishAot>
</PropertyGroup>
Request Delegate Generator improvements: The source generator that creates request delegates for Minimal API endpoints handles more parameter binding scenarios in .NET 10, including additional
TypedResults
return types and complex binding patterns. This reduces the need for manual workarounds that were required in .NET 8/9 when the generator could not produce AOT-safe code for certain endpoint signatures.
Reduced linker warning surface: Many ASP.NET Core framework APIs that previously emitted trim/AOT warnings (IL2xxx/IL3xxx) have been annotated or refactored for AOT compatibility. Projects upgrading from .NET 9 to .NET 10 will see fewer false-positive linker warnings when publishing with
PublishAot
.
OpenAPI in the
webapiaot
template:
The
webapiaot
project template now includes OpenAPI document generation via
Microsoft.AspNetCore.OpenApi
by default, so AOT-published APIs get auto-generated API documentation without additional setup.
Runtime NativeAOT code generation: The .NET 10 runtime improves AOT code generation for struct arguments, enhances loop inversion optimizations, and improves method devirtualization -- resulting in better throughput for AOT-published applications without code changes.
Blazor Server and SignalR: Blazor Server and SignalR remain not supported with Native AOT in .NET 10. Blazor WebAssembly AOT (client-side compilation) is a separate concern covered by [skill:dotnet-aot-wasm]. For Blazor Server apps, continue using JIT deployment.
Compatibility snapshot (.NET 10):
FeatureAOT Support
gRPCFully supported
Minimal APIsPartially supported (most scenarios work)
MVCNot supported
Blazor ServerNot supported
SignalRNot supported
JWT AuthenticationFully supported
CORS, HealthChecks, OutputCachingFully supported
WebSockets, StaticFilesFully supported

.NET 10在ASP.NET Core和运行时Native AOT栈方面带来了多项改进。将目标框架设置为
net10.0
即可自动受益。
xml
<PropertyGroup>
  <TargetFramework>net10.0</TargetFramework>
  <PublishAot>true</PublishAot>
</PropertyGroup>
请求委托生成器改进:为Minimal API端点创建请求委托的源代码生成器在.NET 10中支持更多参数绑定场景,包括额外的
TypedResults
返回类型和复杂绑定模式。这减少了在.NET 8/9中当生成器无法为某些端点签名生成AOT安全代码时所需的手动解决方法。
裁剪警告范围缩小:许多之前会发出裁剪/AOT警告(IL2xxx/IL3xxx)的ASP.NET Core框架API已添加注解或重构为兼容AOT。从.NET 9升级到.NET 10的项目在使用
PublishAot
发布时会看到更少的误报裁剪警告。
webapiaot
模板中的OpenAPI
webapiaot
项目模板现在默认包含通过
Microsoft.AspNetCore.OpenApi
生成的OpenAPI文档,因此AOT发布的API无需额外设置即可自动生成API文档。
运行时NativeAOT代码生成改进:.NET 10运行时优化了结构体参数的AOT代码生成,增强了循环反转优化,并改进了方法去虚拟化——无需修改代码即可提升AOT发布应用的吞吐量。
Blazor Server和SignalR:在.NET 10中,Blazor Server和SignalR仍然不支持Native AOT。Blazor WebAssembly AOT(客户端编译)是一个独立的主题,详见[skill:dotnet-aot-wasm]。对于Blazor Server应用,请继续使用JIT部署。
兼容性快照(.NET 10)
功能AOT支持
gRPC完全支持
Minimal APIs部分支持(大多数场景可正常工作)
MVC不支持
Blazor Server不支持
SignalR不支持
JWT认证完全支持
CORS、健康检查、输出缓存完全支持
WebSockets、静态文件完全支持

Agent Gotchas

常见误区

  1. Do not use
    PublishAot
    in library projects.
    Libraries use
    IsAotCompatible
    (which auto-enables the AOT analyzer).
    PublishAot
    is for applications that produce standalone executables.
  2. Do not use legacy RD.xml for type preservation. RD.xml is a .NET Native/UWP format that is silently ignored by modern .NET AOT. Use ILLink descriptor XML files and
    [DynamicDependency]
    attributes instead.
  3. Do not use
    [DllImport]
    in new AOT code.
    Use
    [LibraryImport]
    (.NET 7+) which generates marshalling at compile time.
    [DllImport]
    may require runtime marshalling that is not available in AOT.
  4. Do not use
    WebApplication.CreateBuilder()
    for AOT APIs.
    Use
    CreateSlimBuilder()
    which excludes reflection-heavy features.
    CreateBuilder()
    includes MVC infrastructure that is not AOT-compatible.
  5. Do not use
    dotnet publish --no-actual-publish
    for analysis.
    That flag does not exist. Use
    dotnet build /p:EnableAotAnalyzer=true /p:EnableTrimAnalyzer=true
    to get diagnostic warnings without publishing.
  6. Do not assume MVC controllers work with Native AOT. MVC relies on reflection for model binding, action filters, and routing. Use Minimal APIs for AOT-published web applications.

  1. 请勿在类库项目中使用
    PublishAot
    。类库应使用
    IsAotCompatible
    (会自动启用AOT分析器)。
    PublishAot
    仅适用于生成独立可执行文件的应用。
  2. 请勿使用旧版RD.xml进行类型保留。RD.xml是.NET Native/UWP格式,现代.NET AOT会自动忽略它。请改用ILLink描述符XML文件和
    [DynamicDependency]
    特性。
  3. 请勿在新的AOT代码中使用
    [DllImport]
    。请使用
    [LibraryImport]
    (.NET 7+),它在编译时生成封送代码。
    [DllImport]
    可能需要AOT不支持的运行时封送。
  4. 请勿为AOT API使用
    WebApplication.CreateBuilder()
    。请使用
    CreateSlimBuilder()
    ,它排除了依赖反射的功能。
    CreateBuilder()
    包含不兼容AOT的MVC基础设施。
  5. 请勿使用
    dotnet publish --no-actual-publish
    进行分析
    。该标志不存在。请使用
    dotnet build /p:EnableAotAnalyzer=true /p:EnableTrimAnalyzer=true
    来获取诊断警告,无需发布。
  6. 请勿假设MVC控制器兼容Native AOT。MVC依赖反射进行模型绑定、动作过滤器和路由。请为AOT发布的Web应用使用Minimal API。

References

参考资料