Dras.biz Just another WordPress site

May 14, 2012

Customizing Saving/Loading Objects

Filed under: SaveIt,SaveIT API Reference — mark @ 12:27

When saving an object all what the SaveContext of SaveIt does is to store it into an internal TableEntry. The real magic comes when saving a class with a Save method or a class with an associated Serializer, this article describes both:

First, the Save and the Load method.
When saving this class:

1
2
3
4
5
public class Foo
{
	public int myValue;
	public string myOtherValue;
}

SaveIt will use a ClassSerializer which basically serialized/deserializes all members of the class, which means that SaveIt will store the myValue and myOtherValue member. Sometimes this is not what you want, for this there are several possibilities, the first one is the usage of the Load and Save Method, for this we extend our existing class:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Foo
{
	public int myValue;
	public string myOtherValue;
 
	void Save(SaveContext context, ref bool allowAutoSerialization)
	{
	}
 
	void Load(LoadContext context, ref bool allowAutoDeserialization)
	{
	}
}

SaveIt will call those methods when serializing or deserializing an instance of the Foo class and you can now specify what should happen when those are called.
Now we can save everything on our way, for this example we save only our int myValue and ignore the string myOtherValue:

1
2
3
4
void Save(SaveContext context, ref bool allowAutoSerialization)
{
	context.Save(myValue);
}

Thats it, we stored the value myValue, BUT SaveIt will still serialize everything else like it will be done without this Save method.
To change this we can set the bool allowAutoSerialization argument to false. SaveIt will then skip all other automatically performed actions.

1
2
3
4
5
void Save(SaveContext context, ref bool allowAutoSerialization)
{
	allowAutoSerialization = false;
	context.Save(myValue);
}

Loading the data inside the Load method, is equally simple:

1
2
3
4
5
6
void Load(LoadContext context, ref bool allowAutoDeserialization)
{
	allowAutoDeserialization = false;
	myValue = context.Load<int>(myValue);
	// or: context.Load(out myValue);
}

The other option to specify custom serialization is by using a type serializer, type serializers inherit from the interface ITypeSerializer:

1
2
3
4
5
6
public interface ITypeSerializer
{
	bool IsUsable(Type type);
	void Serialize(object what, SaveContext context);
	void Deserialize(Type type, LoadContext context);
}

But in most cases you want to use the SaveIt.TypeSerializer.ClassSerializer class to start with, as it performs most operations needed and allows full control on what to serialize/deserialize. But for the next example we will create a fresh Serializer without using ClassSerializer.

Here an example type serializer for the Foo class which does exactly the same thing we did earlier with the Load/Save methods in our Foo class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class FooSerializer : ITypeSerializer
{
	public bool IsUsable(Type type)
	{
		// We only want that this serializer works for the type Foo
		return type == typeof(Foo);
	}
 
	public void Serialize(object what, SaveContext context)
	{
		// This is needed in case our class we want to serialize can contain the Save method
		if (context.RunObjectSaveMethod())
		{
			return;
		}
 
		Foo instance = (Foo)what;
		context.Save(instance.myValue);
	}
 
	public void Deserialize(Type type, LoadContext context)
	{
		// First we need to create the instance of Foo we want to fill with our data
		Foo instance = new Foo();
 
		// Store the new created instance into the context, so SaveIt knows about the created instance and wont create it anew
		context.CurrentInstance = instance;
 
		// This is needed in case our class we want to deserialize can contain the Load method
		if (context.RunObjectLoadMethod())
		{
			return;
		}
 
		instance.myValue = context.Load<int>(myValue);
	}
}

After the TypeSerializer has been created, you need to store it into a static list of TypeSerializers SaveIt may use:

1
ContextBase.TypeSerializers.Add(new FooSerializer());

ContextBase is the base class from the LoadContext and SaveContext class in the SaveIt namespace.

No Comments »

No comments yet.

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by WordPress