Click here to Skip to main content
6,629,885 members and growing! (24,120 online)
Email Password   helpLost your password?
Web Development » Silverlight » General     Intermediate License: The Code Project Open License (CPOL)

Usage of IsolatedStorage Made Easy

By Rohit Shrivastava, AmitKRana

Usage of IsolatedStorage made easy
C# (C# 1.0, C# 2.0, C# 3.0), Windows, .NET (.NET 3.0, .NET 3.5), Silverlight, Architect, Dev
Version:8 (See All)
Posted:28 Jun 2009
Views:3,566
Bookmarked:13 times
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
8 votes for this article.
Popularity: 4.00 Rating: 4.43 out of 5

1

2
1 vote, 12.5%
3

4
7 votes, 87.5%
5

Introduction

There is a very basic need to cache some data at clientside in Silverlight, when we get data using WCF service and want that data to reside at the client side so that the system will not fetch the data every time from the server. This will make sense when we know that the data is kind of static and will not change frequently.

To make use of IsolatedStorage, a developer has to create a file stream and save the data. Ideally in the real world, all data will be kept in memory as an object of some type. Now to store this object in IsolatedStorage, one has to first deserialize it and store it in files and define file names for them. Later this data will be read from the files and will be kept in memory again in the form of an object.

To simplify the above task, I have combined the functionality of IsolatedStorage and DataContractSerializer and created the ClientStorage class which helps the user to store any object directly in the IsolatedStorage, i.e. making object persistent, an interesting feature of OOPs. To achieve a feature of OOPs, one must follow the OOPs approach rather than writing the same code again and again for different objects. This piece of code can be clubbed together and I have named it as ClientStorage.

Background

Silverlight provides two classes, one is IsolatedStorage and another is DataContractSerializer.

Silverlight provides IsolatedStorage class to store data at the client machine. With isolated storage, data is isolated by user and by assembly. Credentials such as the origin or the strong name of the assembly determine assembly identity. Data can also be isolated by application domain, using similar credentials.

DataContractSerializer class is used to serialize and deserialize instances of a type into an XML stream or document. For example, you can create a type named Person with properties that contain essential data, such as a name and address. You can then create and manipulate an instance of the Person class and write all of its property values in an XML document for later retrieval, or in an XML stream for immediate transport. Most important, the DataContractSerializer is used to serialize and deserialize data sent in Silverlight version 2 messages. Apply the DataContractAttribute attribute to classes, and the DataMemberAttribute attribute to class members to specify properties and fields that are serialized.

Inside ClientStorage

ClientStorage is a singleton class that is basically a indexed collection which helps in fetching the objects on the basis of key. It automatically serializes the object and also stores the type of the object, so that it can be de-serialized later. It gives Index based object fetching mechanism which makes life easier.

It contains a Dictionary of key and object. It writes all the keys to keyNames.txt and each object in a separate file. Key names are unique so all the objects will be stored in the file name as <key_name>object.xml.

An indexer is written to fetch the value via providing the key in the index. As soon as any new key is added to the ClientStorage, it adds it to the Dictionary and serializes the Dictionary and stores it in keynames.txt file. Then the newly added object is serialized and stored in a separate file. When object is retrieved from ClientStorage, it first looks for the key existence and then if the object is null, reads the object's XML file, deserializes the object, updates in Dictionary and then returns the object.

private object Retreive(string key)
        {
            object value=null;

            if (CheckForFileExistence(key + KEY_OBJECT_FILE) && 
					keysNTypes.ContainsKey(key))
            {
                if (keysNTypes[key].StoredObject == null)
                {
                    try
                    {
                        using (IsolatedStorageFileStream iStream = 
			new IsolatedStorageFileStream(key + KEY_OBJECT_FILE, 
			FileMode.OpenOrCreate, isoStore))
                        {
                            if (iStream != null)
                            {
                                try
                                {
                                    DataContractSerializer serializer = 
					new DataContractSerializer
					(keysNTypes[key].TypeofObject);
                                    value = serializer.ReadObject(iStream);
                                }
                                catch (Exception)
                                {
                                    // Do nothing simply return null
                                }
                                keysNTypes[key].StoredObject = value;
                                iStream.Close();
                            }
                        }
                    }
                    catch (FileNotFoundException)
                    {
                        throw new KeyNotFoundException();
                    }
                }
                else
                {
                    value = keysNTypes[key].StoredObject;
                }
            }
            return value;
        }

While instantiating the ClientStorage object, it reads the keys file and creates the Dictionary without their objects. When retrieval request comes for any object, then only it fetches the object from the XML file. This way I am minimizing the effort of loading/instantiating the ClientStorage object.

private void ReadKeys(IsolatedStorageFile isoStore)
        {
            IsolatedStorageFileStream iStream = 
		new IsolatedStorageFileStream(ISOLATED_KEY_FILE_NAME, 
              	FileMode.Open, isoStore);
            DataContractSerializer serializer = 
		new DataContractSerializer(keysNTypes.GetType());
            keysNTypes = serializer.ReadObject(iStream) as Dictionary<string>;
        }

Using the Code

The approach is simple and following the habit of using Session and ViewState. When we use Session to store any object in ASP.NET, the developer does not bother where this information will be kept. She/he keeps her/his objects in session when she wanted them to be available throughout the life time of user's session. The same applies to IsolatedStorage, when developer wants to store something per user/application wide data on client machine that would be available cross browser to the application independent of session like persistent for always until user deletes them manually. Then why to complicate things, why not something like ClientStorage[keyname] = object; and it's all done.

// To make use of ClientStorage
ClientStorage[keyname] = object;       
object = ClientStorage[keyname];

TODO

Next, it can be improved/enhanced further to provide versioning support for the objects stored in ClientStorage so that it helps in identifying the stale objects in the ClientStorage and allows to re-fetch/re-creation of that object.

I know this can be improved further, any suggestions or feedback will be highly appreciated.

History

  • 28th June, 2009: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Authors

Rohit Shrivastava


Member

Occupation: Software Developer (Senior)
Company: Contata Solutions
Location: India India

AmitKRana


Member

Location: India India

Other popular Silverlight articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
  (Refresh) 
-- There are no messages in this forum --

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 28 Jun 2009
Editor: Deeksha Shenoy
Copyright 2009 by Rohit Shrivastava, AmitKRana
Everything else Copyright © CodeProject, 1999-2009
Web18 | Advertise on the Code Project