Skip to main content

AOT Compatibility Matrix

This page documents the Native AOT compatibility status for every shipping package. Use this as a reference when planning AOT-published applications.

Summary: the large majority of shipping packages are AOT-compatible. The table below is the per-package authority — read it rather than a headline count. A package marked Not compatible has a documented blocking dependency in an external SDK, not in framework code.

For setup instructions and source generator usage, see the Native AOT Guide.


How to Read This Matrix​

The column answers one question: if you publish ahead-of-time, what will your build tell you?

StatusWhat it means for your buildWhat to do
CleanNo reflection we are aware of. Your publish is silent, and the silence is earned.Nothing.
Warns youReflection is present and annotated, so the compiler flags the exact call at your call site.Read the warning, use the alternative it names, or suppress it deliberately in your own code where your team can review it.
Doesn't warn youReflection is present, but it is internal and suppressed here, so your build will say nothing about it.Your compiler cannot help you for this package. Publish an ahead-of-time binary and exercise these paths before you ship.
Not compatibleIsAotCompatible=false. The package does not claim ahead-of-time compatibility — usually a blocking dependency, sometimes reflection in its own code.
N/ATooling package (analyzer, source generator) — runs at compile time, not at runtime.

Dispatch Packages​

Core​

PackageAOT StatusNotes
Excalibur.DispatchWarns youSource-generated handler resolution via PrecompiledHandlerRegistry. Annotated paths: AddAdaptiveTimeAwareScheduling, AddContextValidation, AddDefaultDispatchPipelines and 58 more. The rest of the surface publishes clean.
Excalibur.Dispatch.AbstractionsWarns youAll interfaces and base types are trim-safe. Annotated paths: AddEventTypesFromAssembly, EnqueueAsync, GetUnsentMessagesAsync and 2 more. The rest of the surface publishes clean.
Excalibur.Dispatch.PatternsWarns youAnnotated paths: ClaimCheckMessageSerializer. The rest of the surface publishes clean.
Excalibur.Dispatch.Patterns.AzureWarns youAnnotated path: the IConfiguration-binding overload of AddAzureBlobClaimCheck, which reflects over the options type. The overload that takes its options in code publishes clean. The rest of the surface publishes clean.
Excalibur.Dispatch.Patterns.ClaimCheck.InMemoryWarns youAnnotated path: the IConfiguration-binding overload of AddInMemoryClaimCheck, which reflects over the options type. The overload that takes its options in code publishes clean. The rest of the surface publishes clean.
Excalibur.Dispatch.Patterns.Hosting.JsonDoesn't warn you

Middleware and Pipeline​

PackageAOT StatusNotes
Excalibur.Dispatch.CachingWarns youCachingMiddleware uses RuntimeFeature.IsDynamicCodeSupported branching. Analysis reports 14 trim/AOT diagnostics on reflection paths in this package; the rest of the surface publishes clean
Excalibur.Dispatch.Resilience.PollyWarns youPolly v8 is AOT-compatible. Annotated paths: AddPollyResilience, UseResilience. The rest of the surface publishes clean.
Excalibur.Dispatch.Validation.FluentValidationWarns youDual-path: AotFluentValidatorResolver + source-gen IAotValidationDispatcher. Annotated paths: WithFluentValidation. The rest of the surface publishes clean.

Serialization​

PackageAOT StatusNotes
Excalibur.Dispatch.Serialization.MemoryPackWarns youMemoryPack uses source generation. Annotated paths: ISerializer. The rest of the surface publishes clean.
Excalibur.Dispatch.Serialization.AvroNot compatibleApache.Avro uses runtime code generation
Excalibur.Dispatch.Serialization.MessagePackNot compatibleMessagePack reflection-based resolvers
Excalibur.Dispatch.Serialization.ProtobufWarns youUses Google.Protobuf (v3.32.1+), which is AOT-compatible. Annotated paths: ISerializer. The rest of the surface publishes clean.

Transport​

PackageAOT StatusNotes
Excalibur.Dispatch.Transport.AbstractionsWarns youCloudEventEncoderAdapter<TOutbound> forwards to the registered ICloudEventEncoder<TOutbound>, which may serialize reflectively. Annotated paths: ToTransportAsync. Each transport's own UseCloudEvents/AddCloudEventsForX registration carries the same annotation, so the signal reaches a consumer who opts into CloudEvents. The rest of the surface publishes clean.
Excalibur.Dispatch.Transport.RabbitMQWarns youBuilder pattern, no reflection. Annotated paths: ToTransportMessageAsync, AddCloudEventsForRabbitMq. The rest of the surface publishes clean.
Excalibur.Dispatch.Transport.AwsSqsWarns youBuilder pattern, no reflection. Annotated paths: ToBatchSqsMessageAsync, ToEventBridgeEventAsync and 4 more, plus the CloudEvents registrations UseCloudEvents, AddCloudEventsForSqs, AddCloudEventsForSns, AddCloudEventsForEventBridge. The rest of the surface publishes clean.
Excalibur.Dispatch.Transport.AzureServiceBusWarns youMessageDeserializerRegistry typed pattern; EventGridTransportSender annotated. Annotated paths: ToTransportMessageAsync, plus the CloudEvents registrations UseCloudEvents, AddCloudEventsForServiceBus, AddCloudEventsForEventHubs. The rest of the surface publishes clean.
Excalibur.Dispatch.Transport.GooglePubSubNot compatibleGoogle Cloud SDK dependency uses reflection. UseCloudEvents and AddCloudEventsForPubSub are separately annotated: the bundled mapper serializes payloads reflectively
Excalibur.Dispatch.Transport.KafkaNot compatibleConfluent.Kafka SchemaRegistry uses Activator.CreateInstance. AddCloudEventsForKafka is separately annotated: the bundled mapper serializes payloads reflectively
Excalibur.Dispatch.Transport.GrpcDoesn't warn youGrpcJsonSerializerContext source-gen JSON for all 10 transport types

Hosting​

PackageAOT StatusNotes
Excalibur.Dispatch.Hosting.AspNetCoreWarns youAnnotated paths: AddDispatch, public static RouteHandlerBuilder Dispat. The rest of the surface publishes clean.
Excalibur.Dispatch.Hosting.AwsLambdaWarns youAnnotated paths: AddAwsLambdaServerless. The rest of the surface publishes clean.
Excalibur.Dispatch.Hosting.AzureFunctionsWarns youAnnotated path: the IConfiguration-binding overload of AddAzureFunctionsServerless, which reflects over the options type. The overload that takes its options in code publishes clean. The rest of the surface publishes clean.
Excalibur.Dispatch.Hosting.GoogleCloudFunctionsWarns youAnnotated path: the IConfiguration-binding overload of AddGoogleCloudFunctionsServerless, which reflects over the options type. The overload that takes its options in code publishes clean. The rest of the surface publishes clean.
Excalibur.Dispatch.Hosting.Serverless.AbstractionsWarns youAnnotated path: the IConfiguration-binding overload of AddServerlessHosting, which reflects over the options type. The overload that takes its options in code publishes clean. The rest of the surface publishes clean.

Observability​

PackageAOT StatusNotes
Excalibur.Dispatch.ObservabilityWarns youUses System.Diagnostics (OTel-aligned). Analysis reports 4 trim/AOT diagnostics on reflection paths in this package; the rest of the surface publishes clean
Excalibur.Dispatch.Observability.AwsClean

Security​

PackageAOT StatusNotes
Excalibur.SecurityWarns youAnnotated paths: AddDispatchSecurity, AddDispatchSecurityMiddleware, AddInputValidation and 8 more. The rest of the surface publishes clean.
Excalibur.Security.AwsNot compatibleAWS SDK v3 (AWSSDK.Core, AWSSDK.SecretsManager) is reflection-based and declares no trim or AOT properties, so the analyzer cannot see its reflection and reports nothing while a native publish fails at link time
Excalibur.Security.AzureClean

Compliance​

PackageAOT StatusNotes
Excalibur.Compliance.AbstractionsClean
Excalibur.ComplianceWarns youReflection paths annotated with [DynamicallyAccessedMembers]. Annotated paths: DynamicallyAccessedMembers, EnforceRetentionAsync, EnqueueAsync and 3 more. The rest of the surface publishes clean.
Excalibur.Compliance.AwsNot compatibleAWS KMS SDK dependency
Excalibur.Compliance.AzureDoesn't warn you
Excalibur.Compliance.VaultDoesn't warn you

Audit Logging​

PackageAOT StatusNotes
Excalibur.AuditLoggingDoesn't warn you
Excalibur.AuditLogging.AwsDoesn't warn you
Excalibur.AuditLogging.DatadogDoesn't warn you
Excalibur.AuditLogging.ElasticsearchDoesn't warn you
Excalibur.AuditLogging.GoogleCloudDoesn't warn you
Excalibur.AuditLogging.OpenSearchDoesn't warn you
Excalibur.AuditLogging.PostgresWarns youAnnotated path: the IConfiguration-binding overload of AddPostgresAuditStore, which reflects over the options type. The overload that takes its options in code publishes clean. The rest of the surface publishes clean.
Excalibur.AuditLogging.SentinelDoesn't warn you
Excalibur.AuditLogging.SplunkDoesn't warn you
Excalibur.AuditLogging.SqlServerDoesn't warn you

Claim Check​

PackageAOT StatusNotes
Excalibur.Dispatch.ClaimCheck.AwsS3Not compatibleAWS S3 SDK dependency
Excalibur.Dispatch.ClaimCheck.GoogleCloudStorageNot compatibleGoogle Cloud Storage SDK dependency

Leader Election​

PackageAOT StatusNotes
Excalibur.Dispatch.LeaderElection.AbstractionsClean

Testing​

PackageAOT StatusNotes
Excalibur.Dispatch.TestingWarns youAnnotated paths: CreateAsyncScope, CreateScope. The rest of the surface publishes clean.
Excalibur.Dispatch.Testing.ShouldlyClean

Tooling (compile-time only)​

PackageAOT StatusNotes
Excalibur.Dispatch (bundled generator)N/ARoslyn source generator (netstandard2.0)
Excalibur.Dispatch (bundled analyzer)N/ARoslyn analyzer (netstandard2.0)
Excalibur.Dispatch.AnalyzersN/ARoslyn analyzer (netstandard2.0)

Excalibur Packages​

Domain and Data Access​

PackageAOT StatusNotes
Excalibur.DomainWarns youAnnotated paths: AddBoundedContextEnforcement, AddImplementations, DefaultBoundedContextValidator and 3 more. The rest of the surface publishes clean.
Excalibur.ApplicationWarns youAnnotated paths: AddActivities. The rest of the surface publishes clean.
Excalibur.Data.AbstractionsClean
Excalibur.DataWarns youAnnotated paths: ExcaliburJsonSerializerOptions. The rest of the surface publishes clean.
Excalibur.Data.InMemoryWarns youAnalysis reports 4 trim/AOT diagnostics on reflection paths in this package; the rest of the surface publishes clean
Excalibur.Data.SqlServerWarns youDapper itself is AOT-compatible. The dead-letter store carries no annotation: its message property bag is serialized through a source-generated JSON context, so it publishes clean and needs no consumer workaround. Annotated path: AddSqlServerPersistence. The rest of the surface publishes clean
Excalibur.Data.PostgresWarns youDapper itself is AOT-compatible. The dead-letter store carries no annotation: its message property bag is serialized through a source-generated JSON context, so it publishes clean and needs no consumer workaround. Annotated paths: the PostgresPersistenceProvider constructor, AddPostgresPersistence, AddPostgresPersistenceFromSection. The rest of the surface publishes clean
Excalibur.Data.MySqlDoesn't warn you
Excalibur.Data.MongoDBWarns youAnalysis reports 8 trim/AOT diagnostics on reflection paths in this package; the rest of the surface publishes clean
Excalibur.Data.RedisDoesn't warn you
Excalibur.Data.ElasticSearchWarns youAnalysis reports 76 trim/AOT diagnostics on reflection paths in this package; the rest of the surface publishes clean
Excalibur.Data.ElasticSearch.AzureWarns youAddAzureKeyVaultCredentialStorage is annotated, so the diagnostic surfaces at your call site rather than in this package's own build.
Excalibur.Data.DataProcessingWarns youAnnotated paths: AddDataProcessing, AddProcessorsFromAssembly, AddRecordHandlersFromAssembly and 1 more. The rest of the surface publishes clean.
Excalibur.Data.CosmosDbNot compatibleCosmosDB SDK uses Expression.Compile()
Excalibur.Data.DynamoDbNot compatibleDynamoDB SDK reflection-based marshalling
Excalibur.Data.FirestoreNot compatibleFirestore SDK uses reflection
Excalibur.Data.OpenSearchNot compatibleOpenSearch SDK dependency

Event Sourcing​

PackageAOT StatusNotes
Excalibur.EventSourcing.AbstractionsWarns youAnnotated paths: public static async Task<CursorPagedResu, public static async Task<IReadOnlyList<o, public static async Task<PagedResult<TPr and 1 more. The rest of the surface publishes clean.
Excalibur.EventSourcingWarns youAnnotated paths: AddEventNotificationHandlersFromAssembly, AddEventSourcing, AddImmutableProjectionHandlersFromAssembly and 25 more. The rest of the surface publishes clean.
Excalibur.EventSourcing.InMemoryDoesn't warn you
Excalibur.EventSourcing.SqlServerWarns youAnalysis reports 28 trim/AOT diagnostics on reflection paths in this package; the rest of the surface publishes clean
Excalibur.EventSourcing.PostgresWarns youAnalysis reports 24 trim/AOT diagnostics on reflection paths in this package; the rest of the surface publishes clean
Excalibur.EventSourcing.MongoDBDoesn't warn youAnalysis reports 8 trim/AOT diagnostics on reflection paths in this package; the rest of the surface publishes clean
Excalibur.EventSourcing.RedisDoesn't warn youAnalysis reports 24 trim/AOT diagnostics on reflection paths in this package; the rest of the surface publishes clean
Excalibur.EventSourcing.SqliteWarns youAnnotated path: the IConfiguration-binding overload of UseSqlite, which reflects over the options type. The overload that takes its options in code publishes clean. The rest of the surface publishes clean.
Excalibur.EventSourcing.AwsS3Doesn't warn youAnalysis reports 12 trim/AOT diagnostics on reflection paths in this package; the rest of the surface publishes clean
Excalibur.EventSourcing.AzureBlobDoesn't warn youAnalysis reports 12 trim/AOT diagnostics on reflection paths in this package; the rest of the surface publishes clean
Excalibur.EventSourcing.GcsDoesn't warn youAnalysis reports 12 trim/AOT diagnostics on reflection paths in this package; the rest of the surface publishes clean
Excalibur.EventSourcing.CosmosDbNot compatibleCosmosDB SDK dependency
Excalibur.EventSourcing.DynamoDbNot compatibleDynamoDB SDK dependency
Excalibur.EventSourcing.FirestoreNot compatibleFirestore SDK dependency

Outbox​

PackageAOT StatusNotes
Excalibur.OutboxWarns youAnnotated paths: AddMultiTransportOutbox, AddOutbox, DispatchPendingMessagesAsync and 6 more. The rest of the surface publishes clean.
Excalibur.Outbox.InMemoryWarns youAnalysis reports 4 trim/AOT diagnostics on reflection paths in this package; the rest of the surface publishes clean
Excalibur.Outbox.SqlServerWarns youAnalysis reports 32 trim/AOT diagnostics on reflection paths in this package; the rest of the surface publishes clean
Excalibur.Outbox.PostgresWarns youAnnotated paths: EnqueueAsync, GetUnsentMessagesAsync. The rest of the surface publishes clean.
Excalibur.Outbox.RedisWarns youAnnotated paths: EnqueueAsync, GetUnsentMessagesAsync. The rest of the surface publishes clean.
Excalibur.Outbox.ElasticSearchWarns youAnnotated paths: EnqueueAsync, GetUnsentMessagesAsync. The rest of the surface publishes clean.
Excalibur.Outbox.CosmosDbNot compatibleCosmosDB SDK dependency
Excalibur.Outbox.DynamoDbNot compatibleDynamoDB SDK dependency
Excalibur.Outbox.FirestoreNot compatibleFirestore SDK dependency
Excalibur.Outbox.MongoDBNot compatibleMongoDB driver dependency

Inbox​

PackageAOT StatusNotes
Excalibur.InboxClean
Excalibur.Inbox.InMemoryClean
Excalibur.Inbox.SqlServerDoesn't warn youUseSqlServer no longer binds configuration for you, so it publishes clean. To read options from configuration, call services.AddOptions<SqlServerInboxOptions>().BindConfiguration("Section:Path") alongside the registration — binding is reflective, so the trim/AOT warning belongs at your own call site where the trimmer can see it.
Excalibur.Inbox.PostgresDoesn't warn you
Excalibur.Inbox.RedisDoesn't warn you
Excalibur.Inbox.ElasticSearchDoesn't warn you
Excalibur.Inbox.MongoDBDoesn't warn you
Excalibur.Inbox.DynamoDbNot compatibleShips Excalibur.Data.DynamoDb, which is not AOT-compatible
Excalibur.Inbox.FirestoreNot compatibleShips Excalibur.Data.Firestore, which is not AOT-compatible
Excalibur.Inbox.CosmosDbNot compatibleCosmosDB SDK dependency

Saga​

PackageAOT StatusNotes
Excalibur.SagaWarns youSource-gen registry population via IPostConfigureOptions pattern. Annotated paths: AddSagas, ProcessEventAsync, the RequestTimeoutAsync overload that carries timeout data (the parameterless overload is AOT-safe) and 5 more. The rest of the surface publishes clean.
Excalibur.Saga.SqlServerWarns youAnnotated paths: AddSqlServerSagaStore, SaveSagaRequest, UseSqlServerSagaStore and 1 more. The rest of the surface publishes clean.
Excalibur.Saga.PostgresWarns youAnnotated paths: AddPostgresSagaStore, SaveSagaRequest. The rest of the surface publishes clean.
Excalibur.Saga.MongoDBWarns youAnnotated path: SaveAsync — saga state is serialized with a reflection-based serializer. The rest of the surface publishes clean.
Excalibur.Saga.DynamoDbNot compatibleShips Excalibur.Data.DynamoDb, which is not AOT-compatible
Excalibur.Saga.FirestoreNot compatibleShips Excalibur.Data.Firestore, which is not AOT-compatible
Excalibur.Saga.CosmosDbNot compatibleCosmosDB SDK dependency

CDC (Change Data Capture)​

PackageAOT StatusNotes
Excalibur.CdcWarns youAnnotated path: the IConfiguration-binding overload of AddCdcHealthCheck, which reflects over the options type. The overload that takes its options in code publishes clean. The rest of the surface publishes clean.
Excalibur.Cdc.SqlServerWarns youAnnotated paths: AddDataChangeHandlersFromAssembly. The rest of the surface publishes clean.
Excalibur.Cdc.PostgresWarns youAnnotated path: UsePostgres — its only overload. The annotation covers the configuration-binding path the builder exposes, so the call site warns even when you configure in code. The rest of the surface publishes clean.
Excalibur.Cdc.MongoDBDoesn't warn you
Excalibur.Cdc.DynamoDbNot compatibleShips Excalibur.Data.DynamoDb, which is not AOT-compatible
Excalibur.Cdc.FirestoreNot compatibleShips Excalibur.Data.Firestore, which is not AOT-compatible
Excalibur.Cdc.CosmosDbNot compatibleCosmosDB SDK dependency

Leader Election​

PackageAOT StatusNotes
Excalibur.LeaderElectionWarns youAnnotated paths: AddLeaderElectionWatcher. The rest of the surface publishes clean.
Excalibur.LeaderElection.InMemoryWarns youAnnotated path: the IConfiguration-binding overload of AddInMemoryLeaderElection, which reflects over the options type. The overload that takes its options in code publishes clean. The rest of the surface publishes clean.
Excalibur.LeaderElection.SqlServerCleanUseSqlServer no longer binds configuration for you, so it publishes clean. To read options from configuration, call services.AddOptions<SqlServerLeaderElectionOptions>().BindConfiguration("Section:Path") alongside the registration — binding is reflective, so the trim/AOT warning belongs at your own call site where the trimmer can see it.
Excalibur.LeaderElection.PostgresCleanUsePostgres no longer binds configuration for you, so it publishes clean. To read options from configuration, call services.AddOptions<PostgresLeaderElectionOptions>().BindConfiguration("Section:Path") alongside the registration — binding is reflective, so the trim/AOT warning belongs at your own call site where the trimmer can see it.
Excalibur.LeaderElection.RedisDoesn't warn you
Excalibur.LeaderElection.MongoDBDoesn't warn you
Excalibur.LeaderElection.ConsulNot compatibleConsul SDK dependency
Excalibur.LeaderElection.KubernetesNot compatibleKubernetes SDK dependency

Hosting​

PackageAOT StatusNotes
Excalibur.HostingWarns youAnnotated paths: AddDispatch, AddExcalibur, AddExcaliburHealthChecks and 1 more. The rest of the surface publishes clean.
Excalibur.Hosting.WebClean
Excalibur.Hosting.AwsClean
Excalibur.Hosting.AwsLambdaWarns youAnnotated paths: AddExcaliburAwsLambdaServerless. The rest of the surface publishes clean.
Excalibur.Hosting.AzureFunctionsWarns youAnnotated path: the IConfiguration-binding overload of AddExcaliburAzureFunctionsServerless, which reflects over the options type. The overload that takes its options in code publishes clean. The rest of the surface publishes clean.
Excalibur.Hosting.GoogleCloudFunctionsWarns youAnnotated path: the IConfiguration-binding overload of AddExcaliburGoogleCloudFunctionsServerless, which reflects over the options type. The overload that takes its options in code publishes clean. The rest of the surface publishes clean.
Excalibur.Hosting.HealthChecksWarns youAnnotated paths: UseExcaliburHealthChecks. The rest of the surface publishes clean.
Excalibur.Hosting.JobsNot compatibleShips Excalibur.Jobs, which is not AOT-compatible
Excalibur.Hosting.ObservabilityClean
Excalibur.Hosting.Logging.SerilogClean

A3 (Authentication, Authorization, Audit)​

PackageAOT StatusNotes
Excalibur.A3Warns youAnnotated paths: AddA3DispatchServices, AddExcaliburA3, ExtractResourceId and 4 more. The rest of the surface publishes clean.
Excalibur.A3.AbstractionsClean
Excalibur.A3.AspNetCoreClean
Excalibur.A3.CoreWarns youAnnotated path: the IConfiguration-binding overload of AddRoles, which reflects over the options type. The overload that takes its options in code publishes clean. The rest of the surface publishes clean.
Excalibur.A3.GovernanceWarns youAnnotated path: the IConfiguration-binding overload of AddOrphanedAccessDetection, which reflects over the options type. The overload that takes its options in code publishes clean. The rest of the surface publishes clean.
Excalibur.A3.Governance.AbstractionsClean
Excalibur.A3.Policy.CedarClean
Excalibur.A3.Policy.OpaClean

Security and Compliance​

PackageAOT StatusNotes
Excalibur.Security.AbstractionsClean
Excalibur.SecurityWarns you[DynamicallyAccessedMembers] annotations for property-level encryption. Annotated paths: AddDispatchSecurity, AddDispatchSecurityMiddleware, AddInputValidation and 8 more. The rest of the surface publishes clean.
Excalibur.Compliance.SqlServerWarns youAnnotated path: the IConfiguration-binding overload of AddSqlServerKeyEscrow, which reflects over the options type. The overload that takes its options in code publishes clean. The rest of the surface publishes clean.
Excalibur.Compliance.PostgresClean
Excalibur.CachingNot compatibleHybridCache uses reflection

Jobs​

PackageAOT StatusNotes
Excalibur.JobsNot compatibleThe projection-rebuild and outbox jobs drive reflective paths; the requirement is annotated at the members that do it
Excalibur.Jobs.AbstractionsClean
Excalibur.Jobs.AwsClean
Excalibur.Jobs.AzureClean
Excalibur.Jobs.CdcNot compatibleShips Excalibur.Jobs, which is not AOT-compatible
Excalibur.Jobs.DataProcessingNot compatibleShips Excalibur.Jobs, which is not AOT-compatible
Excalibur.Jobs.GoogleCloudClean
Excalibur.Jobs.RedisWarns youAnnotated paths: DistributeJobAsync, ReportJobCompletionAsync. The rest of the surface publishes clean.
Excalibur.Jobs.SqlServerNot compatibleShips Excalibur.Jobs, which is not AOT-compatible

Testing​

PackageAOT StatusNotes
Excalibur.TestingClean
Excalibur.Testing.ConformanceNot compatibleTest kits that read stored data back through the store under test, which deserializes reflectively. A trimmed test host is not a supported configuration

Tools​

PackageAOT StatusNotes
Excalibur.Migrate.ToolDoesn't warn you

Metapackages​

PackageAOT StatusNotes
Excalibur.Dispatch.RabbitMQWarns youThe single entry point is annotated, so there is no unannotated path to avoid
Excalibur.Dispatch.AwsWarns youThe single entry point is annotated, so there is no unannotated path to avoid
Excalibur.Dispatch.AzureWarns youThe single entry point is annotated, so there is no unannotated path to avoid
Excalibur.Dispatch.KafkaNot compatibleShips Excalibur.Dispatch.Transport.Kafka, which is not AOT-compatible
Excalibur.Dispatch.PostgresWarns youAnnotated paths: AddDispatchWithPostgres. The rest of the surface publishes clean.
Excalibur.Dispatch.SqlServerWarns youRegisters an outbox, which serializes payloads reflectively. The single entry point is annotated, so there is no unannotated path to avoid
Excalibur.PostgresWarns youAnnotated paths: AddExcaliburPostgres. The rest of the surface publishes clean.
Excalibur.SqlServerWarns youRegisters an outbox, which serializes payloads reflectively. Both entry points are annotated, so there is no unannotated path to avoid

Blocking Dependencies​

These third-party dependencies prevent AOT compatibility in the affected packages:

DependencyBlocking ReasonAffected Packages
Azure CosmosDB SDKExpression.Compile() in LINQ providerCosmosDb data, event sourcing, outbox, inbox, saga, CDC
AWS DynamoDB SDKReflection-based marshallingDynamoDb data, event sourcing, outbox
Google Firestore SDKReflection-based serializationFirestore data, event sourcing, outbox
Confluent.KafkaActivator.CreateInstance for schema strategiesKafka transport
FluentValidationExpression.Compile() for validatorsFluentValidation middleware
Apache.AvroRuntime code generationAvro serialization
MessagePack-CSharpReflection-based resolversMessagePack serialization
protobuf-netExpression.Compile()(none currently — Excalibur.Dispatch.Serialization.Protobuf uses Google.Protobuf, which is AOT-safe)
OpenSearch SDKReflection-based serializationOpenSearch data
Consul SDKReflection-based HTTP clientConsul leader election
Kubernetes SDKReflection-based clientKubernetes leader election

When these dependencies release AOT-compatible versions, the affected packages will be updated.


Consumer Checklist​

To publish an AOT application with Excalibur:

  1. Verify all referenced packages are AOT-safe using the matrix above

  2. Add source generators to your project:

    <!-- The generators and DISP analyzers are bundled in Excalibur.Dispatch; no extra reference needed. -->
    <PackageReference Include="Excalibur.Dispatch" />
  3. Create a JsonSerializerContext for your application types (see Native AOT Guide)

  4. Mark handlers with [AutoRegister] for compile-time DI registration

  5. Publish with AOT:

    dotnet publish -c Release
  6. Check for warnings — and know what their absence does and does not prove.

    Zero IL2xxx/IL3xxx warnings means every reflection path that is annotated is either unused by you or already handled. It does not mean the packages you reference do no reflection: a suppressed site produces zero warnings by construction, which is exactly what suppression is for. So a silent publish is conclusive for a Clean package and for a Warns you package, and proves nothing for a Doesn't warn you one.

  7. For any package in the "Doesn't warn you" column, test the binary, not the build log. Run the published ahead-of-time output and exercise the paths you depend on. That is the only signal available to you for those packages, because the compile-time one has been turned off.

For a Warns you package, [RequiresUnreferencedCode] and [RequiresDynamicCode] propagate the warning to your call site, so you can make the decision where you can see it. That propagation is what the Doesn't warn you column is telling you that you will not get.

Additional Packages​

These packages ship from this repository and were absent from the matrix above. Status is read directly from each project's IsAotCompatible property, the same source the sections above use.

PackageAOT StatusNotes
Excalibur.Dispatch.Compat.MassTransitClean
Excalibur.Dispatch.Compat.MediatRCleanAddMediatRCompat registers a fixed set of adapters and needs no reflection over consumer types, so the whole surface publishes clean.
Excalibur.Dispatch.MigrationNot compatible
Excalibur.Dispatch.Transport.IbmMqNot compatibleNOT compatible. The IBM MQ managed client uses runtime reflection and dynamic assembly loading.
Excalibur.Dispatch.Transport.MqttWarns youBuilder pattern, no reflection. The CloudEvents encoder serializes the payload through reflection-based JSON. Annotated paths: ToTransportMessageAsync, AddCloudEventsForMqtt. The rest of the surface publishes clean.
Excalibur.Dispatch.Transport.PulsarClean
Excalibur.AuditLogging.AbstractionsClean
Excalibur.Compliance.MongoDbClean
Excalibur.Compliance.PdfNot compatible
Excalibur.Data.IdentityMap.SqlServerCleanUseSqlServer no longer binds configuration for you, so it publishes clean. To read options from configuration, call services.AddOptions<SqlServerIdentityMapOptions>().BindConfiguration("Section:Path") alongside the registration — binding is reflective, so the trim/AOT warning belongs at your own call site where the trimmer can see it.
Excalibur.Data.IdentityMapClean
Excalibur.Data.SpannerNot compatibleNOT compatible. Google.Cloud.Spanner.Data uses gRPC + reflection-based value conversion.
Excalibur.EventSourcing.HandlersClean
Excalibur.EventSourcing.OracleDoesn't warn youAnalysis reports 16 trim/AOT diagnostics on reflection paths in this package; the rest of the surface publishes clean
Excalibur.Inbox.OracleDoesn't warn youUseOracle no longer binds configuration for you, so it publishes clean. To read options from configuration, call services.AddOptions<OracleInboxOptions>().BindConfiguration("Section:Path") alongside the registration — binding is reflective, so the trim/AOT warning belongs at your own call site where the trimmer can see it.
Excalibur.MultiTenancyNot compatibleRow-discriminator decoration of open-generic IProjectionStore<T> uses reflective MakeGenericType over the DI descriptor set, so this composition
Excalibur.Operations.Dashboard.EventSourcingClean
Excalibur.Operations.Dashboard.SpaClean
Excalibur.Operations.DashboardClean
Excalibur.Outbox.MartenNot compatible
Excalibur.Outbox.OracleWarns youAnnotated paths: EnqueueAsync, GetUnsentMessagesAsync. The rest of the surface publishes clean.
Excalibur.Saga.OracleWarns youAnnotated paths: AddOracleSagaStore, SaveSagaRequest, UseOracleSagaStore and 1 more. The rest of the surface publishes clean.
Excalibur.Security.AuditLoggingClean
Excalibur.Testing.ContainersNot compatibleFixtures run under a test host, not a trimmed consumer app; reflection in Testcontainers is acceptable here.
Excalibur.Workflows.AbstractionsClean
Excalibur.Workflows.SqlServerClean
Excalibur.WorkflowsDoesn't warn you
Excalibur.Dispatch.AspNetCoreWarns youAnnotated paths: AddDispatchAspNetCore. The rest of the surface publishes clean.