.Net native aot简单体验(三)——Asp.net

发布时间 2023-09-02 21:49:08作者: 天方

微软在.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. 显式添加了序列化的对象上下文 

// Register the JSON serializer context with DI
builder.Services.ConfigureHttpJsonOptions(options =>
{
    options.SerializerOptions.AddContext<AppJsonSerializerContext>();
});

...

// 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的优势也不明显,不过还是希望能尽快完善其缺失的功能的。

 

参考文章