.Net: Best way to deserialise an ever changing object?

Soldato
Joined
5 Mar 2003
Posts
10,771
Location
Nottingham
Hi,
I have a situation where I need to save the state of an object in a database and use that state to repopulate the same object. The four problems are:
  • The object contains public and private data that needs to be stored and repopulated.
  • Extra properties are added to the object (although it will always be backward compatible). These extra properties will have the defaults set in the objects constructor (so no need to populate them, but the old fields must be populated).
  • I have access to the source code of the changing object, but cannot change anything about it.
  • Some of the private data is stored in an internal hashtable.
So those are the problems. At the moment we are using a pretty ropey reflection method, ripping out all the data to XML and storing it in a database. It gets even worse as we have seperate methods to chug through the collection data (hashtables, generic dictionaries etc).

I know there must be a better way to do this - anyone got any pointers?
Cheers.
 
Why not just use standard binary serialisation as implemented in the System.Runtime.Serialization namespaces? Should work fine in your situation.
 
Would that work? I thought if the version or object was a tiny bit different it wouldn't deserialise? We've had it before when different versions of the dll have been on different machines and it's not marshalled correctly...
 
Tried it with the following code:
Code:
[Serializable]
    public class Vehicle
    {
        private Hashtable myValues;

        public string ValueOne
        {
            get { return myValues["ValueOne"].ToString(); }
        }

        public string ValueTwo
        {
            get { return myValues["ValueTwo"].ToString(); }
        }

        public string ValueThree
        {
            get { return myValues["ValueThree"].ToString(); }
        }

        public Vehicle()
        {
            myValues = new Hashtable();
            myValues["ValueOne"] = "SomeValueOne";
            myValues["ValueTwo"] = "SomeValueTwo";
            myValues["ValueThree"] = "SomeValueThree";
        }

        public override string ToString()
        {
            StringBuilder b = new StringBuilder();
            b.AppendFormat("{0}{1}", myValues["ValueOne"].ToString(), Environment.NewLine);
            b.AppendFormat("{0}{1}", myValues["ValueTwo"].ToString(), Environment.NewLine);
            b.AppendFormat("{0}{1}", myValues["ValueThree"].ToString(), Environment.NewLine);
            return b.ToString();
        }
    }

Serialised an object when ValueThree (and all related access) was commented out. Uncommented it and tried to deserialise but it gave a null reference on myValues["ValueThree"].ToString(). Looks like the constructor isn't called so not possible to set defaults?
 
Vai: Thanks for that, it might work. The class is serialisable and not sealed, so I should be able to inherit it and confirm to ISerialisable to set all the defaults... so when the models change I just put the defaults in there.

Will give it a try when I get back from work - thanks!
 
Well this tool is used on loads of different models so if we were to use a db to store all the information it's just over the top and the DBA would tell us to fo basically! Jester, you think there is a problem using OnDeserialise etc?
 
I've had less than a days experience with .NET, but as a general rule of thumb, it's better to map than serialise for DB storage. :)
 
Thanks for ya help guys. It looks as if VTS and OnDeserialized attribute are the solutions to the problem. I've tried a few tests and it seems to work, although not flawlessly (any dictionarys or collections are not correctly deserialised by the time the ondeserialised method is called) but should be enough to work with :)
 
Back
Top Bottom