Monday, May 16, 2011

Silverlight Tip : Using Isolated storage to generically store and retrieve objects

The Code 
A small generic class:

public static class IsolatedStorageHelper
    {
        private static string GetNameFromExpression<T>(Expression<Func<T>> propertyExpression)
        {
            var body = propertyExpression.Body as MemberExpression;            
            string propertyName = body.Member.Name;
            return propertyName;
        }

        public static void SaveData<T>(T data, Expression<Func<T>> fileNameExpression)
        {
            string fileName = GetNameFromExpression(fileNameExpression);
            using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
            {
                using (IsolatedStorageFileStream isfs = new IsolatedStorageFileStream(fileName, FileMode.Create, isf))
                {
                    DataContractSerializer serializer = new DataContractSerializer(typeof(T));
                    serializer.WriteObject(isfs, data);                       
                }
            }
        }
        public static void DeleteData<T>(Expression<Func<T>> fileNameExpression)
        {
            string fileName = GetNameFromExpression(fileNameExpression);
            using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
            {
                try
                {
                    if (isf.FileExists(fileName))
                        isf.DeleteFile(fileName);
                }
                catch
                {
                }
            }
        }

        public static T LoadData<T>(Expression<Func<T>> fileNameExpression,T defaultValue)
        {
            string fileName = GetNameFromExpression(fileNameExpression);
            T data;
            using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
            {                
                try
                {
                    using (IsolatedStorageFileStream isfs = new IsolatedStorageFileStream(fileName, FileMode.Open, isf))
                    {
                        DataContractSerializer serializer = new DataContractSerializer(typeof(T));
                        data = (T)serializer.ReadObject(isfs);
                    }
                }
                catch
                {
                    return defaultValue;
                }
                
            }
            return data;
        }

    }

The Usage
A with this you can simply load objects without magic strings / typecasting with default values :

RememberMe = IsolatedStorageHelper.LoadData<bool>(() => RememberMe,false);
UserName = IsolatedStorageHelper.LoadData<string>(() => UserName,"");
Password= IsolatedStorageHelper.LoadData<string>(() => Password,"");

And just as easily save them:

IsolatedStorageHelper.SaveData(UserName, () => UserName);
IsolatedStorageHelper.SaveData(Password, () => Password);

A user registry for silverlight :)

Enjoy!