EatATaco
EatATaco

Reputation: 709

Good coding practice when saving data to files in .net

To give a bit of a background.

I have created an application that allows users to save settings and then recall the settings at a later date. To do this I have created some serializable objects. I have gotten this to work using the BinaryFormatter without much trouble.

Where I start to run into problems is when I upgrade the software and add new settings. Now my serializable objects do not match and so I have to update the files. I have done this successfully for a few versions. But to do this I try deserializing the file and if it throws an exception, I try with the next version. . .and then the next. . .and then the next. . . until I find the right one. Then I have to write conversion functions for each of old versions to convert it into the newest version. I did create a "revision" file as well, so I can just check up front what version they have and then upgrade it, but I still have to keep a lot of different "versions" alive and write the conversion functions for all of them. . . which seems inherently messy to me and prone to bloat later on down the line if I keep going this route.

There has to be a better way to do this, I just am not sure how.

Thanks

Upvotes: 5

Views: 1410

Answers (6)

i486
i486

Reputation: 6564

XML format is for such cases. You will find the necessary old settings in very early version of settings file. And even the old version can handle XML settings created from newer version. It does not work "automatically" i.e. with method like Serialize/Deserialize, but writing conversion functions is not easier or faster.

Upvotes: 1

Paul Farry
Paul Farry

Reputation: 4768

You could have a look at ProtoBuf-Net http://code.google.com/p/protobuf-net/wiki/GettingStarted if you are doing Binary because all these things are covered regarding versioning etc. It is also very compact. It also is actively developed and if you potentially have cross platform requirements if you use a .proto file you can also achieve that.

If you would like people to be possibly able to edit the settings (outside of your program) then you could use the XML* serialisation methods.

Upvotes: 0

Andy
Andy

Reputation: 8562

This is exactly what the Settings class is for. You define default values in your app.config, and then a user can change them and when you save, their changes will save to a location in their user profile. When you read them you'll just get the modified settings.

This link is for VS 2005, but it works exactly the same in VS 2012: http://msdn.microsoft.com/en-us/library/aa730869(v=vs.80).aspx

Found the link for VS2012: http://msdn.microsoft.com/EN-US/library/k4s6c3a0(v=VS.110,d=hv.2).aspx

Upvotes: 2

Loren Pechtel
Loren Pechtel

Reputation: 9083

In addition to naming the fields as others have suggested this sort of thing just cries out for version numbers.

Upvotes: 0

DiskJunky
DiskJunky

Reputation: 4971

actually this can be done by adding a [DefaultValue()] attribute to the newer properties on your settings objects - at least for XML serialization. I haven't attempted this using binary serialzation. For xml, this means that they are "optional" and the serialization will not break when loading old version of the files. You can find this attribute in the System.ComponentModel namespace as so;

class MySettings
{
    public int MaxNumLogins { get; set; }

    // specify the value to default to if it's not present in the serialized file...
    [DefaultValue(0)]
    public int CacheTimeoutMinutes { get; set; }
}

Upvotes: 0

IAbstract
IAbstract

Reputation: 19881

You need to write a serialization binder to resolve assemblies.

For settings, I use a Dictionary<string, byte[]> to save to file. I serialize the dictionary and all is well. When I add new settings, I provide a default setting if not found in the settings file.

Also, if you are adding fields to a serialized object, you can decorate with [Optional].

Upvotes: 3

Related Questions