Windows 8.1 – Data Persistance

Windows Store applications can persist runtime state, user preferences, and other settings using different mechanisms:

  • Local: Persistent data that exists only on the current device.
  • Roaming: Data that exists on all devices on which the user has installed the app.
  • Temporary: Data that could be removed by the system at any time.
var localSettings = ApplicationData.Current.LocalSettings;
var roamingSettings = ApplicationData.Current.RoamingSettings;
var tempFolder = ApplicationData.Current.TemporaryFolder;

In this post I will share my helper class to store objects using the LocalSettings container.

One problem I found when I tried to save an object to the LocalSettings is that it only supports the following types:

UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double
Boolean
Char16, String
DateTime, TimeSpan
GUID, Point, Size, Rect
ApplicationDataCompositeValue

For the application that I am working on I needed to store an instance of my settings data class, this class was already prepared for serialization. After playing around a little bit I found an easy solution implementing a helper class that serializes my object to XML and saves it as string.

StorageManager.cs

using Windows.Storage;

namespace WindowsStore.Common.Storage
{
    public class StorageManager
    {
        /// <summary>
        /// Initializes a new instance of the  <see cref="StorageManager" /> class.
        /// As the LocalSettings is divided in containers the constructor needs the key of the container to use.
        /// </summary>
        /// <param name="containerKey">The key.</param>
        /// <param name="isRoaming">if set to <c>true</c> [is roaming].</param>
        public StorageManager(string containerKey, bool isRoaming)
        {
            if (isRoaming)
            {
                InitializeRoamingAppContainer(containerKey);
            }
            else
            {
                InitializeLocalAppContainer(containerKey);
            }
        }

        /// <summary>
        /// Determines whether the local storage contains an object associated to the specified key.
        /// </summary>
        public bool Contains(string key)
        {
            return AppSettingsContainer.Values.ContainsKey(key);
        }

        /// <summary>
        /// Saves the specified object associated to the specified key.
        /// </summary>
        public void Save(string key, object value)
        {
            var serializedValue = XMLSerializer.SerializeToString(value);

            if (AppSettingsContainer.Values.ContainsKey(key))
            {
                AppSettingsContainer.Values[key] = serializedValue;
            }
            else
            {
                AppSettingsContainer.Values.Add(key, serializedValue);
            }
        }

        /// <summary>
        /// Loads an object associated to the specified key.
        /// </summary>
        public T Load<T>(string key)
        {
            if (AppSettingsContainer.Values.ContainsKey(key))
            {
                return XMLSerializer.DeserializeFromString<T>(AppSettingsContainer.Values[key].ToString());
            }

            return default(T);
        }

        /// <summary>
        /// Removes the object associated to the specified key.
        /// </summary>
        public bool Remove(string key)
        {
            if (AppSettingsContainer.Values.ContainsKey(key))
            {
                return AppSettingsContainer.Values.Remove(key);
            }
            return false;
        }

        #region privates

        /// <summary>
        /// Initializes a roaming application container.
        /// </summary>
        /// <param name="containerKey">The container key.</param>
        private void InitializeRoamingAppContainer(string containerKey)
        {
            // todo RoamingQuota
            if (!ApplicationData.Current.RoamingSettings.Containers.ContainsKey(containerKey))
            {
                ApplicationData.Current.RoamingSettings.CreateContainer(containerKey,
                    ApplicationDataCreateDisposition.Always);
            }

            this.AppSettingsContainer = ApplicationData.Current.RoamingSettings.Containers[containerKey];
        }

        /// <summary>
        /// Initializes a local application container.
        /// </summary>
        /// <param name="containerKey">The container key.</param>
        private void InitializeLocalAppContainer(string containerKey)
        {
            if (!ApplicationData.Current.LocalSettings.Containers.ContainsKey(containerKey))
            {
                ApplicationData.Current.LocalSettings.CreateContainer(containerKey,
                    ApplicationDataCreateDisposition.Always);
            }

            this.AppSettingsContainer = ApplicationData.Current.LocalSettings.Containers[containerKey];
        }

        /// <summary>
        /// Gets or sets the application settings container.
        /// </summary>
        private ApplicationDataContainer AppSettingsContainer { get; set; }

        #endregion

    }
}

XMLSerializer.cs

using System.IO;
using System.Xml.Serialization;

namespace WindowsStore.Common.Storage
{
    public static class XMLSerializer
    {
        /// <summary>
        /// Serializes an object to string using XML.
        /// </summary>
        /// <param name="obj">The object.</param>
        public static string SerializeToString(object obj)
        {
            XmlSerializer serializer = new XmlSerializer(obj.GetType());
            using (StringWriter writer = new StringWriter())
            {
                serializer.Serialize(writer, obj);
                return writer.ToString();
            }
        }

        /// <summary>
        /// De-serializes an object from XML string.
        /// </summary>
        /// <typeparam name="T">Type of the object to deserialize</typeparam>
        /// <param name="xml">The XML.</param>
        public static T DeserializeFromString<T>(string xml)
        {
            XmlSerializer deserializer = new XmlSerializer(typeof(T));
            using (StringReader reader = new StringReader(xml))
            {
                return (T)deserializer.Deserialize(reader);
            }
        }
    }
}

References:

Your feedback is important...

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.