1. Problem
You want to serialize on disk the state of your objects, to load them later.
2. Solution
You must use XmlSerializer in combination with the IsolatedStorage classes to serialize the state of your objects in a file.
3. How It Works
The XmlSerializer
class serializes (and deserializes) objects to and from XML documents.
In serialization, we convert an object and its properties to a serial
format (in this case, XML) that can be stored (in our case) or
transported (in the case of services, for example). Deserialization is
the process of re-creating the object from XML, by decorating the
objects that correspond to XmlElement, and their properties that correspond to XmlAttribute.
4. The Code
For this recipe, we have chosen to complete the application logic of 7Drum by using the ExerciseManager class to save and load the exercises.
Just to refresh your memory, as you can see from the diagram in Figure 1, one of the entities involved in this recipe is ExerciseSettings, whose persistence logic (in this case, in the isolated storage) is handled by the ExerciseManager class, which deals simply with loading and saving a list of exercises.
The first method that you want to consider is Save. The code is written as follows:
public static void Save(List<ExerciseSettings> exercises)
{
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
using (var fileStream = store.CreateFile("exercises.xml"))
using (var writer = new StreamWriter(fileStream))
{
XmlSerializer ser = new XmlSerializer(typeof(List<ExerciseSettings>));
ser.Serialize(writer, exercises);
writer.Close();
}
}
This code, which makes extensive use of the construct using,
behaves almost exactly the same way as the code of the previous recipe.
In practice, you return the store associated with your application.
Then in this store, you create the XML files for the exercises, you
associate the StreamWriter to this fileStream, and finally, thanks to the XmlSerializer
class, you write the XML serialization that results in the list of
exercises. Closing the stream commits the changes, and the using
statements coming at the end of the scope disposes the three variablese
writer, fileStream and store.
In this way, you just serialized into isolated storage a list of ExerciseSettings.
It is obvious that if your application requires more than one entity
domain, you will have no problem using this code. If you have any
doubts, the only thing you need to revise is the use of the XmlSerializer class.
The other method to analyze now is the Load method, which will deserialize the data from the XML file in our class:
public static List<ExerciseSettings> Load()
{
List<ExerciseSettings> exercises = new List<ExerciseSettings>();
using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
if (storage.FileExists("exercises.xml"))
{
using (IsolatedStorageFileStream stream = storage.OpenFile("exercises.xml",
FileMode.Open))
{
XmlSerializer xml = new XmlSerializer(typeof(List<ExerciseSettings>));
exercises = xml.Deserialize(stream) as List<ExerciseSettings>;
stream.Close();
}
}
return exercises;
}
This code is not so difficult to understand if you analyze it step by step:
Create a list of ExerciseSettings.
Return to our store (at this point, it's clear that if you want to access the isolated storage this is a necessary step).
If there is an XML file called exercises in the store, do the following:
Open a stream pointing to the file.
Create an XmlSerializer class to list the ExerciseSettings.
Deserialize the stream in the list of ExerciseSettings.
At this point, our application 7Drum is ready to save and upload lists of exercises, to keep them between sessions of our application.
5. Usage
After adding the implementation of the two methods of the class ExerciseManager,
start the application from Visual Studio by pressing F5. To test if you
have correctly written the code save a list of exercises and close 7Drum. Then reopen and check that between sessions the whole list of exercises has been saved.