> ## Documentation Index
> Fetch the complete documentation index at: https://docs.westyx.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# .NET SDK - Trimming and Native AOT

> All six packages declare IsAotCompatible, what makes that work, and the one annotated exception.

All six packages declare `IsAotCompatible`, which means a trimmed or Native-AOT application can use them and the analysers will tell you if it cannot.

```xml theme={null}
<PublishAot>true</PublishAot>
<!-- or -->
<PublishTrimmed>true</PublishTrimmed>
<TrimMode>full</TrimMode>
```

Nothing else is needed. There is no separate AOT package and no source-generator reference to add.

## What makes it work

Every JSON call routes through a source-generated `JsonSerializerContext`. The reflection-based serializer is what usually breaks under trimming - it discovers properties at run time, the trimmer removes what it cannot see being used, and the failure arrives as a runtime exception in production rather than a warning at build time. The source-generated context is resolved at compile time, so the trimmer keeps exactly what is used and the AOT compiler has real code to compile.

## The one annotated exception

`AddWestyxNexusSecrets<T>` carries `[RequiresUnreferencedCode]` and `[RequiresDynamicCode]`:

```csharp theme={null}
builder.Services.AddWestyxNexusSecrets<DatabaseOptions>("database");
// IL2026 / IL3050 in an AOT or trimmed publish
```

Binding an arbitrary options type is a generic call the configuration binding generator cannot generate for, so that one path stays reflection-based - and says so at the call site rather than failing at run time. Two ways forward:

* **Read the secret directly.** `client.GetSecret("database.password")` involves no binding and is fully compatible.
* **Keep the binder and accept the warning**, if the option type is simple enough that you can satisfy yourself the trimmer will keep it. `[DynamicDependency]` on your own options type is the supported way to say so.

Everything else - the client, the `IConfiguration` provider, feature management, the OpenFeature provider and the `aws_iam` credential source - publishes clean.

## How it is proven

Not by declaring the property. `IsAotCompatible` turns the analysers on, but ILLink and the AOT compiler only see a library's real reachability through an application that roots it - a library compiled on its own reports nothing.

The pipeline publishes a harness application that references all six packages, touches each one's entry points, and roots every package as a `TrimmerRootAssembly` so the trimmer analyses all of each one rather than only what the harness happens to reach. The job fails on any `IL2xxx` or `IL3xxx` diagnostic from a Westyx package. It runs on every commit, so a change that quietly reintroduces reflection is caught where it is made.
