Repository navigation
feat: aot support #233
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: aot support #233
Changes from all commits
25682eb
c756964
d12bc71
be8ed83
b887266
69ea478
fbc56b8
21e0d33
ec353fa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,16 +15,16 @@ Supported Objects: | |
| - [System.Text.Json.Nodes.JsonValue](https://docs.microsoft.com/en-us/dotnet/api/system.text.json.nodes.jsonvalue) | ||
| - [System.Text.Json.JsonElement](https://docs.microsoft.com/en-us/dotnet/api/system.text.json.jsonelement) | ||
| - [System.Text.Json.JsonDocument](https://docs.microsoft.com/en-us/dotnet/api/system.text.json.jsondocument) | ||
| - [System.Text.Json.Serialization.JsonIgnoreAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.text.json.serialization.jsonignoreattribute) | ||
| - Conditions - controls whether a property is included while serializing and deserializing | ||
| - Always = Ignore during serialization and deserialization (default) | ||
| - Never = Include during serialization and deserialization | ||
| - WhenWritingNull = Ignore during serialization when the value is `null` | ||
| - WhenWritingDefault = Ignore during serialization when the value is the type's default value | ||
| - WhenWriting = Ignore during serialization | ||
| - WhenReading = Ignore during deserialization | ||
|
|
||
| Conditional `WhenWritingNull` and `WhenWritingDefault` properties remain readable during deserialization. Properties ignored with `Always` or `WhenReading` are treated as known ignored properties and skipped when they appear in YAML input. | ||
| - [System.Text.Json.Serialization.JsonIgnoreAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.text.json.serialization.jsonignoreattribute) | ||
| - Conditions - controls whether a property is included while serializing and deserializing | ||
| - Always = Ignore during serialization and deserialization (default) | ||
| - Never = Include during serialization and deserialization | ||
| - WhenWritingNull = Ignore during serialization when the value is `null` | ||
| - WhenWritingDefault = Ignore during serialization when the value is the type's default value | ||
| - WhenWriting = Ignore during serialization | ||
| - WhenReading = Ignore during deserialization | ||
| Conditional `WhenWritingNull` and `WhenWritingDefault` properties remain readable during deserialization. Properties ignored with `Always` or `WhenReading` are treated as known ignored properties and skipped when they appear in YAML input. | ||
| - [System.Text.Json.Serialization.JsonPropertyNameAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.text.json.serialization.jsonpropertynameattribute) | ||
| - Name - Specifies the property name that is present in the JSON/YAML when serializing and deserializing. | ||
| - [System.Text.Json.Serialization.JsonPropertyOrderAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.text.json.serialization.jsonpropertyorderattribute) | ||
|
|
@@ -73,18 +73,62 @@ var deserializer = new DeserializerBuilder() | |
| var myObject = deserializer.Deserialize<MyType>(yaml) | ||
| ``` | ||
|
|
||
| ### Trimming | ||
|
|
||
| The library is trim-analyzed. Its default `YamlConverter` methods and `AddSystemTextJson` extensions for YamlDotNet's reflection based builders are marked as requiring unreferenced code. For trimmed applications, use the `YamlConverter` overloads that accept a generated `StaticContext`, or YamlDotNet's static builders. | ||
|
|
||
| Add the `Vecc.YamlDotNet.Analyzers.StaticGenerator` package to the consuming application, declare a partial `StaticContext` with `[YamlStaticContext]` and `[YamlSerializable(typeof(MyModel))]`, then pass that context to `YamlConverter.Serialize` and `YamlConverter.Deserialize<T>`. Register all application model types used by the context, including enum types. The `AddSystemTextJson` builder extensions also support YamlDotNet's static builder types. | ||
| ### Trimming | ||
|
|
||
| The [`samples`](samples) project demonstrates static-context serialization and deserialization, JSON property attributes, extension data, ordering and default-value options, unmatched-property handling, and direct static-builder configuration. It also runs as the trimmed consumer smoke test in CI. | ||
|
|
||
| For applications configuring YamlDotNet's static builders directly, register each model type and enum in the generated static context. The context must include public model properties, fields, and constructors, and enum public fields for `JsonStringEnumMemberNameAttribute`. For `IDictionary<string, JsonElement>` extension data, values may be JSON scalars, dictionaries with string keys, sequences, or existing `JsonElement`, `JsonDocument`, or `JsonNode` instances. Arbitrary CLR objects require runtime JSON metadata and are rejected. `IDictionary<string, object>` extension data retains its values as objects. | ||
|
|
||
| Extension-data properties using a concrete dictionary type other than `Dictionary<string, object>` or `Dictionary<string, JsonElement>` should be initialized before deserialization. | ||
|
|
||
| ### Inspired By | ||
|
|
||
| [https://github.com/tomlm/YamlConvert](https://github.com/tomlm/YamlConvert) | ||
| Use the generated `StaticContext` overloads for trimmed or Native AOT apps. Install the generator with `dotnet add package Vecc.YamlDotNet.Analyzers.StaticGenerator`, register every model and enum, and preserve members that carry System.Text.Json attributes: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win The README recommends the package that this PR had to replace. Line 78 tells users to install Add a note that nested model types need a package version that includes the fix. Alternatively, state the minimum package version once it is released. 🧰 Tools🪛 LanguageTool[style] ~78-~78: Consider using “who” when you are referring to people instead of objects. (THAT_WHO) 🤖 Prompt for AI Agents |
||
|
|
||
| ```csharp | ||
| using System.Diagnostics.CodeAnalysis; | ||
| using System.Text.Json.Serialization; | ||
| using YamlDotNet.Serialization; | ||
| using YamlDotNet.System.Text.Json; | ||
|
|
||
| [YamlStaticContext] | ||
| [YamlSerializable(typeof(ServiceConfig))] | ||
| [YamlSerializable(typeof(DeploymentMode))] | ||
| public partial class AppYamlContext : StaticContext | ||
| { | ||
| } | ||
|
|
||
| public sealed class ServiceConfig | ||
| { | ||
| [JsonPropertyName("service-name")] | ||
| public string Name { get; set; } = "api"; | ||
|
|
||
| public DeploymentMode Mode { get; set; } | ||
| } | ||
|
|
||
| public enum DeploymentMode | ||
| { | ||
| [JsonStringEnumMemberName("production")] | ||
| Production, | ||
| } | ||
|
|
||
| internal static class Program | ||
| { | ||
| [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ServiceConfig))] | ||
| [DynamicDependency(DynamicallyAccessedMemberTypes.PublicFields, typeof(DeploymentMode))] | ||
| private static void Main() | ||
| { | ||
| var context = new AppYamlContext(); | ||
| var yaml = YamlConverter.Serialize(new ServiceConfig { Name = "api" }, context); | ||
| var config = YamlConverter.Deserialize<ServiceConfig>(yaml, context); | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| To use YamlDotNet's builder APIs with the same context: | ||
|
|
||
| ```csharp | ||
| var serializer = new StaticSerializerBuilder(context) | ||
| .AddSystemTextJson() | ||
| .Build(); | ||
| var deserializer = new StaticDeserializerBuilder(context) | ||
| .AddSystemTextJson() | ||
| .Build(); | ||
|
|
||
| var yaml = serializer.Serialize(config); | ||
| var roundTripped = deserializer.Deserialize<ServiceConfig>(yaml); | ||
| ``` | ||
|
|
||
| Set `<PublishAot>true</PublishAot>` in the app project for Native AOT, or `<PublishTrimmed>true</PublishTrimmed>` for trimming, then publish for your target runtime identifier. The context APIs use generated YamlDotNet model metadata; contextless `YamlConverter` methods and YamlDotNet's reflection builders require unreferenced code. | ||
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
Uh oh!
There was an error while loading. Please reload this page.