I am using Sterling DB in a WP7 app and trying to implement a custom serialiser for, hopefully, performance gains.
I’ll provide an example (excuse all formatting, trying to compress it to keep it small). Given a type that inherits List<string>:
public class TypedList : List<string>
{
public Guid ObjectId { get; set; }
public TypedList() { }
public TypedList(int count) : base(count) { }
}
And it’s serialiser:
public class TypedListSerializer : Wintellect.Sterling.Serialization.BaseSerializer
{
public override bool CanSerialize(Type targetType)
{
return targetType.Equals(typeof(TypedList));
}
public override object Deserialize(Type type, BinaryReader reader)
{
int count = reader.ReadInt32();
var list = new TypedList(count);
for (int i = 0; i < count; i++)
list.Add(reader.ReadString());
return list;
}
public override void Serialize(object target, BinaryWriter writer)
{
var list = (TypedList)target;
writer.Write(list.Count);
foreach (string s in list)
writer.Write(s);
}
}
I register the serialiser with the engine:
_engine = new SterlingEngine();
_engine.SterlingDatabase.RegisterSerializer<TypedListSerializer>();
_engine.Activate();
Assuming a table of TypedList types. Now when I try to save/load this type on the Sterling instance:
// _instance is a class that inherits BaseDatabaseInstance from the Sterling code.
_instance.Save<TypedList>(list);
_instance.Flush();
_instance.Load<TypedList>(g); // g is Guid.
It calls into CanSerialize, but the Type it is given is that of T from List<T>, the class I inherit from. If you change string to int, it tells me the type is an int.
Has anyone else had this problem? Is this a Sterling issue or one with type information on generics?
Update: as per Marc’s suggestion about inheritance, I amended my type to the following:
public class TypedList
{
public Guid ObjectId { get; set; }
public List<int> Items { get; set; }
public TypedList()
{
Items = new List<int>();
}
}
What the serializer appears to be doing is checking the properties of TypedList instead of the type itself. I’m guessing this is now a fault with how I’m using Sterling. My table registration line looks like this:
protected override List<ITableDefinition> RegisterTables()
{
return new List<ITableDefinition>
{
CreateTableDefinition<TypedList, Guid>(l => l.ObjectId)
};
}
Just for what it’s worth – Sterling expects to be in full control of “top level” entities so it can build the keys, indexes, and other parts that it needs to function. That is why it never calls the custom serializer for the top-level entity (the one you define to have indexes and keys). The custom serializers are meant for properties off of those tables. The fix above is correct because it now sees the list as a property rather than the top level “item” it is trying to serialize.