The YamlSerializer overloads that take options use reflection, which trimming and native AOT can’t rely on. Declare a YamlSerializerContext and pass its generated metadata instead. The generator ships in the OneYaml package; there is nothing else to install.
<PropertyGroup> <PublishAot>true</PublishAot> </PropertyGroup>
using OneYaml; // Generated metadata instead of reflection: safe to trim and to publish as native AOT. string src = """ retries: 3 endpoint: https://example.com tags: [web, public] """; Settings settings = YamlSerializer.Deserialize(src, AppYamlContext.Default.Settings)!; Console.WriteLine($"{settings.Retries} retries against {settings.Endpoint.Host}"); Console.Write(YamlSerializer.Serialize(settings with { Retries = 5 }, AppYamlContext.Default.Settings)); // YamlDocument takes generated metadata too. using var doc = YamlDocument.Parse(src); doc.Set("/tags", new List<string> { "web", "internal" }, AppYamlContext.Default.ListString); Console.WriteLine(doc); record Settings(int Retries, Uri Endpoint, List<string> Tags); [YamlSerializable(typeof(Settings))] partial class AppYamlContext : YamlSerializerContext;
3 retries against example.com retries: 5 endpoint: https://example.com tags: - web - public retries: 3 endpoint: https://example.com tags: [web, internal]
That output is from the native executable built by dotnet publish -c Release, with warnings treated as errors.
Good to know
- The generator writes a
YamlTypeInfo<T>property on the context for each[YamlSerializable]type and for every type those reach, such asListStringforList<string>above. - Generated and reflection metadata bind the same way: attributes, converters, polymorphism and extension data work with both.
- For options other than the defaults, create the context with them,
new AppYamlContext(new YamlSerializerOptions { ... }), or setTypeInfoResolver = AppYamlContext.Defaulton options you already pass around. - With
PublishTrimmedorPublishAot, reflection-based binding is off by default. Set the MSBuild propertyYamlSerializerIsReflectionEnabledByDefaulttotrueto keep it. - Mistakes in a context, such as a context that isn’t
partial, are build-time diagnosticsOY0001toOY0010.
More in source generation and native AOT.
Trim warnings, publish results and YamlDotNet compared: C# YAML with native AOT.