Skip to content

Native AOT & Trimming

Stato reale della compatibilità Native AOT / trimming dell’ecosistema Pragmatic.Design e cosa aspettarsi.

Pragmatic adotta il principio Source-Generator-First: la topologia e i contratti sono risolti a compile-time, e il runtime evita la reflection. Questo rende il cuore del framework (Actions, Endpoints, Persistence, Result, Mapping, Validation, Composition) sostanzialmente reflection-free: il codice che il SG genera è tipato e statico.

Tuttavia “AOT-ready” non è ancora letteralmente vero per l’intero ecosistema. Alcuni moduli usano API .NET che richiedono reflection o codegen a runtime, e il compilatore le segnala.

Un dotnet build produce un numero consistente di warning IL*:

WarningSignificatoCausa tipica in Pragmatic
IL2026RequiresUnreferencedCode — non trim-safeJsonSerializer senza JsonSerializerContext; mapping di delegati negli endpoint SignalR
IL3050RequiresDynamicCode — non AOT-safeJsonSerializer reflection-based; proxy SignalR
IL2091/IL2087/IL2067/IL2090parametro/argomento generico senza annotazione DynamicallyAccessedMembersAddSingleton<,>/AddScoped<,>/ActivatorUtilities.CreateInstance su tipi generici non annotati
NETSDK1210IsAotCompatible non supportato per il TFMprogetti analyzer/codefixer (netstandard2.0) — benigno: gli analyzer non vengono mai compilati AOT

I warning non sono uniformi. Le aree con codice reflection-dependent oggi:

  • Pragmatic.Agent.ProtocolJsonWireFormat usa JsonSerializer senza source-gen context (IL2026/IL3050).
  • Pragmatic.ControlPlane.SignalR — SignalR usa proxy e mapping di delegati: intrinsecamente non AOT/trim-friendly (IL2026/IL3050).
  • Pragmatic.LoggingPragmaticWindowsEventLogProvider serializza in JSON via reflection (IL2026/IL3050).
  • Pragmatic.Abstractions, Pragmatic.Storage, Pragmatic.Authorization, Pragmatic.Logging — extension DI con generici non annotati (IL2091 ecc.) per decorator, UseStorage<T>, AddPermissionProvider<T>, UseStorage audit.

Il cuore SG-driven (Actions/Endpoints/Persistence/Result/Mapping/Validation) non genera questa classe di warning: il codice generato è statico.

  • Build standard (JIT): nessun impatto. I warning IL* non sono errori; l’app gira normalmente.
  • App PublishTrimmed: il trimming può rimuovere tipi usati via reflection nei moduli sopra. Verifica con un test end-to-end. In caso di problemi, preserva i tipi con TrimmerRootDescriptor o evita il modulo interessato.
  • Native AOT: non garantito end-to-end. I percorsi con JsonSerializer reflection-based e SignalR non sono AOT-safe. Per un’app AOT, isola questi moduli (es. ControlPlane.SignalR) in un processo non-AOT, oppure non usarli.

Il framework è reflection-free nel core SG-driven; l’AOT end-to-end non è garantito per via di alcuni percorsi periferici:

  1. Warning IL2091 e affini — provengono dai parametri generici di alcune extension DI. Non sono errori e non impattano la build/run JIT standard.
  2. IL2026/IL3050 da JSON — alcuni percorsi usano System.Text.Json reflection-based (es. Agent.Protocol, provider Windows Event Log). Per AOT, preferisci JsonSerializerContext (source generation) o isola questi percorsi.
  3. SignalRControlPlane.SignalR non è AOT-compatibile per natura di SignalR: richiede JIT.

In breve: descrivi il framework come reflection-free nel core, con AOT pieno non garantito per i moduli che usano JSON reflection o SignalR.

ScenarioStato
Build/run JIT standard✅ pienamente supportato
PublishTrimmed⚠️ verifica E2E; alcuni moduli usano reflection
Native AOT end-to-end❌ non garantito — JSON reflection + SignalR
Core SG-driven (Actions/Persistence/…)✅ reflection-free