微軟在.net 8中已經支持了對.net的aot支持,通過Asp.net的AOT,可以獲取aot的傳統三大優勢
-
更小的磁盤佔用
-
更快的啓動時間
-
更小的內存佔用
下圖簡單的展示了這一特點:
由於aot本身的限制和開發時間限制,不是所有的特性都能支持,目前支持的情況如下:
其中缺失兩個大頭是MVC和SingalR,看來老項目和大項目是暫時無緣aot了。估計和這些特性嚴重依賴反射有關,不過在一些小項目中還是可以體驗一把的。
簡單示例
可以通過dotnet new webapiaot命令生成一個帶webapi的aot示例程序
dotnet new webapiaot -o MyFirstAotWebApi
其代碼如下
using System.Text.Json.Serialization;
var builder = WebApplication.CreateSlimBuilder(args);
builder.Services.ConfigureHttpJsonOptions(options =>
{
options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default);
});
var app = builder.Build();
var sampleTodos = new Todo[] {
new(1, "Walk the dog"),
new(2, "Do the dishes", DateOnly.FromDateTime(DateTime.Now)),
new(3, "Do the laundry", DateOnly.FromDateTime(DateTime.Now.AddDays(1))),
new(4, "Clean the bathroom"),
new(5, "Clean the car", DateOnly.FromDateTime(DateTime.Now.AddDays(2)))
};
var todosApi = app.MapGroup("/todos");
todosApi.MapGet("/", () => sampleTodos);
todosApi.MapGet("/{id}", (int id) =>
sampleTodos.FirstOrDefault(a => a.Id == id) is { } todo
? Results.Ok(todo)
: Results.NotFound());
app.Run();
public record Todo(int Id, string? Title, DateOnly? DueBy = null, bool IsComplete = false);
[JsonSerializable(typeof(Todo[]))]
internal partial class AppJsonSerializerContext : JsonSerializerContext
{
}
可以看到大體上是一個Minimal api示例,和傳統模式主要區別是:
1. 通過WebApplication.CreateSlimBuilder
函數來創建一個功能受限的WebBuilder (aot專用)
2. 顯式添加了序列化的對象上下文
builder.Services.ConfigureHttpJsonOptions(options =>
{
options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default);
});
...
// Add types used in your Minimal APIs to source generated JSON serializer content
[JsonSerializable(typeof(Todo[]))]
internal partial class AppJsonSerializerContext : JsonSerializerContext
{
}
小結
asp.net支持aot意味着我們能用C#在內存,磁盤等資源受限環境編寫服務,無疑更是增強了.net程序的應用場景,目前通過aot的方式實現一些簡單的native web服務還是非常容易的。
目前還是有不少特性無法支持,大型項目aot還是有困難的,雖然aot的優勢在大型項目上aot的優勢也不明顯,不過還是希望能儘快完善其缺失的功能的。