WP7 – Tombstoning simplified, less duplication

James Ashley posted a great tip on simplifying tombstoning by abstracting IsolatedStorageSettings.ApplicationSettings and PhoneApplicationService.Current.State to a common interface IDataStorage.  This makes storing either temporary state data or more permanent settings data much easier with less code.

This was a very good post but the duplication on the two IDataStorage implementations made me cringe a little.  (Remember DRY?)  I knew there was a better way.  I also didn’t need a unique token in my scenario.  I was storing one instance of a plain old settings class.  This would require token generation (or a static string) for the backup in the closing event and also in my ViewModelLocator where I would restore the settings class.  Again, I didn’t like the duplication of the key.  I realize I may have a need for a unique key down the rode but I would prefer not to provide one until then.

So I created a base class which holds the core backup/restore logic and takes in a dictionary<string,object>.  My two implementations inherit from the base and pass the appropriate dictionary (IsolatedStorageSettings.ApplicationSettings or PhoneApplicationService.Current.State).  I made the backup method generic so I could take the type and use it to generate a token if none was passed.  This allows me to persist any one type object in the store without a token at a time.  If the need arises I can always add a token for multiple type instances.  I’m using an optional token parameter on the methods (a new feature for .NET 4).

Here is the code.

public interface IDataStorage
{
bool Backup<T>(T value, string token);
T Restore<T>(string token);
}
public class DataStorageBase
{
protected bool Backup<T>(IDictionary<string, object> bag, T value, string token)
{
if ((object)value == null)
return false;

SetToken<T>(ref token);

if (bag.ContainsKey(token))
bag[token] = value;
else
bag.Add(token, value);

return true;
}

protected T Restore<T>(IDictionary<string, object> bag, string token)
{
SetToken<T>(ref token);

if (!bag.ContainsKey(token))
return default(T);

return (T)bag[token];
}

protected void SetToken<T>(ref string token)
{
if (string.IsNullOrEmpty(token))
token = typeof(T).FullName;
}
}
public class PersistentDataStorage : DataStorageBase, IDataStorage
{
private IsolatedStorageSettings _store;

public PersistentDataStorage()
{
_store = IsolatedStorageSettings.ApplicationSettings;
}

public bool Backup<T>(T value, string token = null)
{
var output = base.Backup<T>(_store, value, token);
_store.Save();
return output;
}

public T Restore<T>(string token = null)
{
return base.Restore<T>(_store, token);
}
}
public class TransientDataStorage : DataStorageBase, IDataStorage
{
private IDictionary<string, object> _store;

public TransientDataStorage()
{
_store = PhoneApplicationService.Current.State;
}

public bool Backup<T>(T value, string token = null)
{
return base.Backup(_store, value, token);
}

public T Restore<T>(string token = null)
{
return base.Restore<T>(_store, token);
}
}

If you have further improvements or concerns please share them.

2 thoughts on “WP7 – Tombstoning simplified, less duplication”

  1. Pingback: The best resources for Windows Phone 7 Development

  2. Pingback: Mister Goodcat | Attribute-based transient Tombstoning

Leave a Reply