aaubry / YamlDotNet

YamlDotNet is a .NET library for YAML
MIT License
2.48k stars 466 forks source link

Order for inheritance #870

Open Develeon64 opened 7 months ago

Develeon64 commented 7 months ago

Hello there!

The question in short is: Can I change to order, so the members of inherited classes get serialized first, without manually sorting everything?

More info: I want to use YAML to configure my app. Every time I read the configuration file I write the just read contents back to normalize it. For my logger I have a base class defining two members, that every logger should have:

public abstract class LogConfigBase {
    public bool Enabled { get; set; } = false;
    public byte Level   { get; set; } = 0;
}

And now I'm using this to define the default behavior of all loggers and 3 specific ones:

public class LogConfig : LogConfigBase {
    public LogConsoleConfig Console { get; set; } = new();
    public LogFileConfig    File    { get; set; } = new();
    public LogSystemConfig  System  { get; set; } = new();
}
public class LogConsoleConfig : LogConfigBase {
    public bool Colorized { get; set; } = true;
}
public class LogFileConfig : LogConfigBase {
    public string Path { get; set; } = "Logs/";
}
public class LogSystemConfig : LogConfigBase {
    public int Id { get; set; } = 0;
}

When serializing this the inherited members are placed behind every other members. But I'd like them to be always at the top.

logging:
  enabled: true
  level: 1
  console:
    enabled: true
    level: 1
    colorized: true
  file:
    enabled: true
    level: 3
    path: Logs/
  system:
    enabled: true
    level: 5
    id: 1234567890

Instead of

logging:
  console:
    colorized: true
    enabled: true
    level: 1
  file:
    path: Logs/
    enabled: true
    level: 3
  system:
    id: 1234567890
    enabled: true
    level: 5
  enabled: true
  level: 1

Can I achieve this in a quick and simple way without creating a custom SortedTypeInspector?

EdwardCooke commented 7 months ago

The way the pre-built typeinspectors are setup is that it just reads the properties/fields on the object, itself, it doesn't take into account whether the field/property is from the inherited types or not, so you'll need to build your own, here's a link to the prebuilt type converter to give you a starting point, it's pretty easy to implement.

https://github.com/aaubry/YamlDotNet/blob/847230593e95750d4294ca72c98a4bd46bdcf265/YamlDotNet/Serialization/TypeInspectors/ReadablePropertiesTypeInspector.cs#L33

EdwardCooke commented 7 months ago

You could also use the YamlMember attribute and set the order on your classes, kind of a pain, but it would work.