0

I have a host of classes including the normal designs of object hierarchies and interfaces, base classes, etc. from a project where I cannot modify any code. I have another payload class in my project which uses composition to encapsulate information from the other classes and contain properties in the payload class whose types are the classes from the other project.

Now I have a need to be able to create an instance of the payload class containing instances of those other classes and serialize it to Base64 string for transmission.

Issue is since I cannot touch the code for the other classes, I cannot add serialization attributes (for .NET binary formatter/protobuf-net). I was also trying to look at using protobuf-net without attributes, but since the object hierarchy is too deep, it seemed to be too complicated to create.

Can somebody tell me a better choice to go ahead with the serialization/deserialization part without modifying the existing code.

Sample code to illustrate the requirement is shown below:

void Main()
{
    var b = new B();
    b.SetStatus("This is B");

    var c = new C { Name = "C", Value = 100};

    var payload = new Payload(b, c);

    var serializedData = SerializeToString<Payload>(payload);

    serializedData.Dump();
}

private static TData DeserializeFromString<TData>(string settings)
{
    byte[] b = Convert.FromBase64String(settings);
    using (var stream = new MemoryStream(b))
    {
        var formatter = new BinaryFormatter();
        stream.Seek(0, SeekOrigin.Begin);
        return (TData)formatter.Deserialize(stream);
    }
}

private static string SerializeToString<TData>(TData settings)
{
    using (var stream = new MemoryStream())
    {
        var formatter = new BinaryFormatter();
        formatter.Serialize(stream, settings);
        stream.Flush();
        stream.Position = 0;
        return Convert.ToBase64String(stream.ToArray());
    }
}

public class A
{
    public string Id { get; set; }
    public string StatusMsg {get;protected set;}
    public virtual void SetStatus(string msg)
    {
        StatusMsg = msg;
    }
}

public class B : A
{
    public B()
    {
        Id = new Guid().ToString();
    }

    public override void SetStatus(string msg)
    {
        base.SetStatus(msg);
    }
}

public class C
{
    public string Name
    {
        get;
        set;
    }

    public Int32 Value
    {
        get;
        set;
    }
}

public class Payload
{
    public B PropertyB { get; set; }
    public C PropertyC { get; set; }

    public Payload(B b, C c)
    {
        this.PropertyB = b;
        this.PropertyC = c;
    }
}
Soumya Kar
  • 11
  • 4

2 Answers2

1

Without adding configuration attributes, you have a few options:

  • use a serialize that won't care: XmlSerializer or Json.NET might work if you're lucky
  • accept the runtime config work of something like protobuf-net or one of the others; it probably isn't as much work as you expect (heck, drop me an email with real code and I might be able to do it)
  • wrote the serialization entirely manually
  • write a DTO layer - a basic model with attributes etc that works well with your chosen serializer - and either write code to map between the two models, or use a tool like auto-mapper

Personally, when serialization configuration gets tricky, my default option is "write a DTO model".

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Is there any sample code which shows the usage of Protobuf without using attributes for any decently nested object hierarchy. – Soumya Kar Jun 18 '18 at 06:17
0

I don't understand why protobuf would not work but you can do the serialization manually if you don't mind.

In that case, create a BinaryWriter and then write everything you need to be able to deserialize it back again using a BinaryReader. Doing it this way you will get a very compact representation tailored for you specific needs which is also very fast. But it's a bit more work also. General purpose serialization can be verbose and slow but is almost always preferred in any case.

But I still don't get why using any existing attribute-less serialization method wouldn't work. You should probably start by really understand why it doesn't work with for instance protobuf or JSON.NET. You mentioned "too deep hierarchy". How deep is that?

Andreas Zita
  • 7,232
  • 6
  • 54
  • 115
  • If it is too much work to configure a few attribute-equivalent settings for protobuf-net's runtime config, then it is presumably too much work to do this too – Marc Gravell Jun 14 '18 at 18:35