Спасибо за обзор! Приходилось раньше несколько раз делать легковесные веб-серверы как раз с использованием NativeAOT и Reflection-free mode (ныне <IlcDisableReflection> вырезан начиная с .NET 9), используя только Kestrel. Для этого просто ссылаемся на ASP.NET в нашем .NET проекте примерно таким образом:
И пишем свою собственную логику используя неймспейс Microsoft.AspNetCore.Server.Kestrel - там все достаточно просто. Похоже, что когда в следующий раз придется это делать, можно будет остановиться на Minimal API, что несомненно удобнее, ведь в нем из коробки уже реализован роутинг и аутентификация. Один момент в вашей статье хотел уточнить - если уж мы используем такой подход, наверное следует отказаться от Reflection целиком, в т.ч. от сериализации моделей средствами ASP.NET (если они еще не перешли на source generators) и получение MethodInfo в вашем примере с OpenAPI. Наконец, вместо ORM и Queriable использовать ADO - DbConnection, DbCommand. Не так уж много кода потребует это все, тем более что достаточно выработать паттерн один раз и переиспользовать его в дальнейшей разработке. Поэтому подойдет, наверное, даже для средне-крупных проектов. К слову, на этапе компоновки бинаря (таргет LinkNative) весь лишний код вырезался и получался бинарь размером не более 5 Мб. Minimal API через <Project Sdk="..."/> давал минимум 12 Мб. Надо проверить, как сейчас с этим дело обстоит у Minimal API.
Unsafe.InitBlock(memory, 0, 8 * 8); // Очищаем память, ибо она грязная
Можно этого не делать. Дотнет по умолчанию инициализирует нулями стековые массивы, выделенные с помощью stackalloc. В дотнете все наоборот: чтобы массив был наполнен неопределенными байтами, нужно в декларации метода указать атрибут [SkipLocalsInit]. Есть также вариант где-то в модуле указать [module: SkipLocalsInit].
Еще важное уточнение про SignalR: он не поддерживает компиляцию NativeAOT, т.к. широко полагается на reflection. И уж тем более ничего работать не будет с <IlcDisableReflection>true</IlcDisableReflection>
Спасибо за обзор! Приходилось раньше несколько раз делать легковесные веб-серверы как раз с использованием NativeAOT и Reflection-free mode (ныне
<IlcDisableReflection>
вырезан начиная с .NET 9), используя только Kestrel. Для этого просто ссылаемся на ASP.NET в нашем .NET проекте примерно таким образом:И пишем свою собственную логику используя неймспейс
Microsoft.AspNetCore.Server.Kestrel
- там все достаточно просто.Похоже, что когда в следующий раз придется это делать, можно будет остановиться на Minimal API, что несомненно удобнее, ведь в нем из коробки уже реализован роутинг и аутентификация. Один момент в вашей статье хотел уточнить - если уж мы используем такой подход, наверное следует отказаться от Reflection целиком, в т.ч. от сериализации моделей средствами ASP.NET (если они еще не перешли на source generators) и получение MethodInfo в вашем примере с OpenAPI. Наконец, вместо ORM и Queriable использовать ADO - DbConnection, DbCommand. Не так уж много кода потребует это все, тем более что достаточно выработать паттерн один раз и переиспользовать его в дальнейшей разработке. Поэтому подойдет, наверное, даже для средне-крупных проектов.
К слову, на этапе компоновки бинаря (таргет LinkNative) весь лишний код вырезался и получался бинарь размером не более 5 Мб. Minimal API через
<Project Sdk="..."/>
давал минимум 12 Мб. Надо проверить, как сейчас с этим дело обстоит у Minimal API.А минусы будут?)
Можно этого не делать. Дотнет по умолчанию инициализирует нулями стековые массивы, выделенные с помощью stackalloc. В дотнете все наоборот: чтобы массив был наполнен неопределенными байтами, нужно в декларации метода указать атрибут [SkipLocalsInit]. Есть также вариант где-то в модуле указать [module: SkipLocalsInit].
Еще важное уточнение про SignalR: он не поддерживает компиляцию NativeAOT, т.к. широко полагается на reflection. И уж тем более ничего работать не будет с
<IlcDisableReflection>true</IlcDisableReflection>