Question

I've been having a hard time figuring out what is the best method to create a "Data Bag" class that can also serialize its data using Protobuf-Net's lightweight serialization, for which I create my own TypeModel. I'm trying to avoid storing the data as Objects. Bascially, something that can do:

DataBag bag = new DataBag();

bag.Add<T>("dataName", value);
bag.Get<T>("dataName");

My solution was to create a wrapper class that has a member of each of my serializable types, and then use two sorting dictionaries whose keys are my types, and provide the correct action to set and get the value, like so:

public class Datum
{
    public int AsInt;
    public string AsString;
    public bool AsBool;
    public int[] AsIntArray;
    public string[] AsStringArray;
    public bool[] AsBoolArray;
}

The bag class builds two static sorting dictionaries and the dictionary that will be serialized like so:

private static Dictionary<Type, Action<Object, Datum>> ValueSet { get; set; }
private static Dictionary<Type, Func<Datum, Object>> ValueGet { get; set; }

private Dictionary<string, Datum> Data { get; set; }

....

ValueSet.Add(typeof(int), (value, datum) => datum.AsInt = (int)value);
ValueGet.Add(typeof(int), (datum) => datum.AsInt);

Then on the methods themselves I do:

public void Add<T>(string name, Object value)
{
    Datum datum = new Datum();
    ValueSet[typeof(T)](value, datum);
    Data.Add(name, datum);
}

public T Get<T>(string name)
{
    return (T)ValueGet[typeof(T)](Data[name]);
}

The problem I have with this approach is that as the amount of serializable objects increases, I have to keep maintaining the class and add new entries on the sorting dictionaries along with more members on the Datum wrapper. Is there an easier way to do this?

Was it helpful?

Solution

protobuf-net isn't designed to store data bags; it is designed to work with known contracts, lot least because the protobuf format is very light on metadata.

You could perhaps use the extension data API, but the problem there is that data doesn't have names (because the protobuf format never stores names) - it has field numbers. If you can use numbers, support for storing, retrieving and round-tripping ad-hoc data is built in.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top