Skip to content
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

Overriding the name of a type dynamically #914

Open
martinjt opened this issue Mar 16, 2024 · 1 comment
Open

Overriding the name of a type dynamically #914

martinjt opened this issue Mar 16, 2024 · 1 comment

Comments

@martinjt
Copy link

I'm playing around with building a class that will model how the OpenTelemetry Collector's config works.

Specifically, they have a format that takes a list of components, but does them as Objects

receivers:
   otlp/1:
     <stuff>
   otlp/2:
    <stuff>

What I want to be able to do is represent that as a list in code (since the OTLP and OTLP/2 objects are the same thing.

So what I want to do is "just" override the name part, and the rendering of the List as a objects.

The classes will look something like this:

public class Config
{
   public List<Receivers> Receivers { get; } = [];
}

public abstract class Receiver
{
   public abstract string ReceiverType;
   public string ReceiverName;
}

Is this possible, I've been struggling to make it work.

@EdwardCooke
Copy link
Collaborator

Yes, you can do this using the IYamlConvertible interface,

using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Serialization;


var data = new Config();
data.Receivers.Add(new Receiver());
data.Receivers.Add(new Receiver());
data.Receivers.Add(new Receiver());

var serializer = new SerializerBuilder().Build();
var yaml = serializer.Serialize(data);
Console.WriteLine(yaml);

public class Config : IYamlConvertible
{
    public List<Receiver> Receivers { get; } = [];

    public void Read(IParser parser, Type expectedType, ObjectDeserializer nestedObjectDeserializer)
    {
    }

    public void Write(IEmitter emitter, ObjectSerializer nestedObjectSerializer)
    {
        emitter.Emit(new YamlDotNet.Core.Events.MappingStart());
        emitter.Emit(new Scalar("Receivers"));
        emitter.Emit(new YamlDotNet.Core.Events.MappingStart());
        
        for (var ordinal = 0; ordinal < Receivers.Count; ordinal++)
        {
            emitter.Emit(new Scalar($"otlp/{ordinal + 1}"));
            nestedObjectSerializer(Receivers[ordinal], typeof(Receiver));
        }

        emitter.Emit(new YamlDotNet.Core.Events.MappingEnd());
        emitter.Emit(new YamlDotNet.Core.Events.MappingEnd());
    }
}

public class Receiver
{
    public string ReceiverType = Guid.NewGuid().ToString();
    public string ReceiverName = Guid.NewGuid().ToString();
}

Results in

Receivers:
  otlp/1:
    ReceiverType: ca5a6d4f-7faa-4420-8257-e97a5bdbda00
    ReceiverName: 900e3564-2859-4277-9f29-674b16f597ed
  otlp/2:
    ReceiverType: ce04b24a-96f3-4a8c-a331-43474a3fb6ea
    ReceiverName: a13e3668-f6b3-49ba-a2a5-9947182e08f9
  otlp/3:
    ReceiverType: 55e810bb-6e44-43c5-90db-6e25e7f6258e
    ReceiverName: fdf65d79-906f-4927-be96-37701a47177d

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants