Open
Description
Feature 特性
正确标记裁剪不兼容的 API 或为其补充给 ILC 的类型使用信息以消除编译期(发布期)产生的 ILC 警告
简要描述原因
虽然 FreeSql 声明自己支持 AOT,但是在发布期产生的 ILXXXX 警告通常代表 ILC 无法确保给定的 API 在经过裁剪后能够正常运作;所以在源码中对这些依赖动态特性的API进行标注是很重要的,因为这些额外的 Attribute 能够帮助 ILC 决定要保留哪些类型或类型的成员(以使得原本经过裁剪导致错误的API变得可用),以及用户是否使用了根本无法在AOT环境调用的API(以确保AOT发布失败来避免用户获得本就不可用的应用程序)
可以查看 准备 .NET 库以进行剪裁 文档以获取更多和裁剪 / 正确支持AOT相关的信息
使用场景
对 .Net 应用程序进行 AOT 编译时
亟待解决的 IL 错误汇总
我编写了一个极小的 C# AOT Minimal API 应用程序以检查常见 API 的使用情况,此项目在发布时会产生若干 IL 警告
using System.Text.Json.Serialization;
using FreeSql;
using FreeSql.DataAnnotations;
using Microsoft.AspNetCore.Mvc;
using DataType = FreeSql.DataType;
var builder = WebApplication.CreateSlimBuilder(args);
builder.Services.ConfigureHttpJsonOptions(option =>
option.SerializerOptions.TypeInfoResolver = ApplicationJsonContext.Default);
builder.Services.AddSingleton<IFreeSql>(_ => new FreeSqlBuilder()
// .UseAdoConnectionPool(true)
.UseConnectionString(DataType.Sqlite, "data source=application_data.db")
// .UseMonitorCommand(cmd => Console.WriteLine($"SqlCommand:\n{cmd.CommandText}"))
.UseAutoSyncStructure(true)
.Build()
);
var app = builder.Build();
app.MapGet("/add", async ([FromHeader(Name = nameof(name))] string name, [FromHeader(Name = nameof(score))] int score, IFreeSql sql) =>
{
await sql.InsertOrUpdate<LeaderBoardItem>().SetSource(new LeaderBoardItem(name, score)).ExecuteAffrowsAsync();
return Results.Ok();
});
app.MapGet("/check", (IFreeSql sql) => sql.Select<LeaderBoardItem>().ToListAsync());
app.Run();
[JsonSerializable(typeof(List<LeaderBoardItem>))]
internal partial class ApplicationJsonContext : JsonSerializerContext;
internal record LeaderBoardItem(
[property: Column(IsPrimary = true)] string Name,
int Score
);
警告类型 | 数量 | 描述 | 示例 | 潜在风险 |
---|---|---|---|---|
动态代码生成 (IL3050) | ~50 | 使用需要运行时生成代码的 API | Expression.Lambda() |
AOT 编译时无法生成代码 |
类型反射缺少注释 (IL2070/IL2075) | ~45 | 没有适当 DynamicallyAccessedMembers 注解的反射 |
GetType().GetMethods() |
修剪可能会删除被反射访问的成员 |
动态类型创建 (IL3050) | ~35 | 运行时创建泛型类型 | MakeGenericType() |
AOT 环境无法生成动态类型 |
表达式构建 (IL2026) | ~10 | 使用字符串创建属性表达式 | Expression.Property(expr, "Name") |
修剪可能移除表达式引用的成员 |
单文件部署 (IL3000/IL3002) | 3 | 使用不支持单文件发布的 API | Assembly.Location |
在单文件应用中会抛出异常 |
Metadata
Metadata
Assignees
Labels
No labels