Serialization vs. program updates

G

Guest

Hi,

Just before I invent my own solution... :)

I'm developing a program where I use binary serialization of the data the
program holds. Know and then the serialized objecst will be modified, e.g.
with a new field, or perhaps the removal of a field. Depending on the
changes, the program will not be able to deserialize the stored data. Is
there any technique I can read about somewhere dealing with this issue.

Regards Jesper
 
N

Nicholas Paldino [.NET/C# MVP]

Jesper,

Yes, you can implement the ISerializable interface on the type, and then
handle serialization yourself. You would be able to check for the existence
of fields, and set values for fields that weren't persisted in the
ISerializable interface implementation.

For more information on custom serialization, you can check out the
section of the MSDN documentation titled "Custom Serialization", located at:

http://msdn2.microsoft.com/en-us/library/ty01x675.aspx
 
P

Peter Duniho

Yes, you can implement the ISerializable interface on the type, and
then
handle serialization yourself. You would be able to check for the
existence
of fields, and set values for fields that weren't persisted in the
ISerializable interface implementation.

Okay, so I admit I'm a complete novice at serialization, so my apologies
if this is a dumb question, but...

My first approach to a situation like this would be to try to introduce
some sort of versioning logic. Specifically, keep the main data object
class and the serializing objects separate. The main data object would
include constructors to take any version of a serializing object I've
made, and handle missing or new fields appropriately. I'd always
serialize using the newest version of the serializing object (or if you
like, the main data object class could always be the "newest version",
though I expect you'd run into class naming issues doing that, requiring
you to rename the class each time it changed?), and rely on the
deserializing process to instantiate the relevant version which could then
be used to construct the main data object.

My reasoning being that I'm "scared" of having to implement custom
serialization. :) That is, I'm sure I could learn it if I had to, but it
seems like a lot of trouble to go to if I can solve the problem from a
higher-level point of view.

So, what's wrong with that idea? :)

Pete
 
S

sloan

You gotta pick one or the other:


If you want backwards compatability, you need to implement ISerializable and
handle the changed/new stuff yourself.


If you want easy, you have to keep the same object "contract".
 
J

John Vottero

Jesper said:
Hi,

Just before I invent my own solution... :)

I'm developing a program where I use binary serialization of the data the
program holds. Know and then the serialized objecst will be modified, e.g.
with a new field, or perhaps the removal of a field. Depending on the
changes, the program will not be able to deserialize the stored data. Is
there any technique I can read about somewhere dealing with this issue.

Search for "Version Tolerant Serialization" and you should find this:

http://msdn2.microsoft.com/en-us/library/ms229752.aspx
 
P

Peter Duniho

You gotta pick one or the other:

If you want backwards compatability, you need to implement ISerializable
and handle the changed/new stuff yourself.

Why? What is it about my proposal that doesn't work?

For example:

class SaveDataVersion1
{
// Serializable class representing the original version of the
data structure
}

class SaveDataVersion2
{
// Serializable class representing the second version of the data
structure
}

class InternalData
{
public InternalData(SaveDataVersion1 initData)
{
// Initialize based on SaveDataVersion1
}

public InternalData(SaveDataVersion2 initData)
{
// Initialize based on SaveDataVersion2
}
}
If you want easy, you have to keep the same object "contract".

The above code seems easy enough to me, and yet allows for multiple
versions of the serializable data.

Pete
 
J

John Vottero

Peter Duniho said:
Why? What is it about my proposal that doesn't work?

For example:

class SaveDataVersion1
{
// Serializable class representing the original version of the
data structure
}

class SaveDataVersion2
{
// Serializable class representing the second version of the data
structure
}

class InternalData
{
public InternalData(SaveDataVersion1 initData)
{
// Initialize based on SaveDataVersion1
}

public InternalData(SaveDataVersion2 initData)
{
// Initialize based on SaveDataVersion2
}
}


The above code seems easy enough to me, and yet allows for multiple
versions of the serializable data.

There's nothing wrong with your approach but, implementing ISerializable
would be a lot easier. V2.0 of the .NET Framework added support for version
tolerant serialization which makes things even easier.
 
P

Peter Duniho

There's nothing wrong with your approach but, implementing ISerializable
would be a lot easier.

If you say so. I'm not sure what could be easier than specifying some
fields, and writing a tiny amount of code that is essentially a sequence
of assignments. But as I said, I don't know what goes into writing a
custom serializing class, so maybe it in fact is even easier than that.
V2.0 of the .NET Framework added support for version tolerant
serialization which makes things even easier.

I had no idea until the link was posted...I intend to read through that
and see if it makes sense to me. Certainly if .NET actually handles
versioning for serialized data, that seems like the way to go.

Pete
 
J

John Vottero

Peter Duniho said:
If you say so. I'm not sure what could be easier than specifying some
fields, and writing a tiny amount of code that is essentially a sequence
of assignments. But as I said, I don't know what goes into writing a
custom serializing class, so maybe it in fact is even easier than that.

Specifying some fields and writing a sequence of assigments is basically
what's involved in implementing ISerializable. There's really nothing to it
although, version tolerant serialization mostly eliminates the need to do
it.

Here's an example of implementing ISerializable for the Widget class:

#region Implementation of ISerializable

/// <summary>
/// Deserialization constructor.
/// </summary>
private Widget(SerializationInfo info, StreamingContext context)
: base (info, context)
{
m_WidgetID = info.GetInt32("WidgetID");
m_WidgetName = info.GetString("WidgetName");

//
// Properties added in V2
//
try
{
m_SpecificValues = info.GetString("SpecificValues");
m_Application = info.GetString("Application");
}
catch (SerializationException)
{
//
// Serialization exception, we must be deserializing a V1
object
//
m_SpecificValues = string.Empty;
m_Application = string.Empty;
}
}

/// <summary>
/// GetObjectData which serializes this Method.
/// </summary>
[SecurityPermission(SecurityAction.Demand,
SerializationFormatter=true)]
public override void GetObjectData(SerializationInfo info,
StreamingContext context)
{
base.GetObjectData(info, context);

info.AddValue("MethodID", m_MethodID);
info.AddValue("MethodName", m_MethodName);

info.AddValue("SpecificValues", m_SpecificValues);
info.AddValue("Application", m_Application);
}
#endregion
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top