IsolatedStorage ORM Prototype

I have no doubt someone else has already created something similar to this, but I wanted to take my crack at it for the application I am writing.

The idea was I wanted to create something that would manage my entities and save/read them from IsolatedStorage for a Windows Phone 7 app.  I understand that using reflection on a mobile device is something you really do try to avoid; to that end, I have reduced the amount to the bare essential.

The following code snippet shows a sample use case:

   1: var repository = new IsolatedStorageRepository();

   2: private void Button_Click(object sender, RoutedEventArgs e)

   3: {

   4:     repository.SaveChanges();

   5: }


   7: private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)

   8: {

   9:     StorageItem item = repository.StorageItems.FirstOrDefault();


  11:     if (item != null)

  12:     {

  13:         txtTwitter.Text = item.TwitterHandle;

  14:         txtAccessCode.Text = item.AccessCode;

  15:     }

  16: }

Most repository patterns tend to be based off some sort of code generation.  Not in this case, since the aim is to abstract away the IsolatedFileStorage, which is nothing more then file access.  Because of this, we allow the user to define their own repository derivation (IsolatedStorageRepository in this case).  Below is the code that is required for this repository:

   1: public class IsolatedStorageRepository : RepositoryBase

   2: {

   3:     public IRepositoryCollection StorageItems

   4:     {

   5:         get;

   6:         set;

   7:     }


   9:     public IsolatedStorageRepository()

  10:     {

  11:         StorageItems = RepositoryCollectionFactory.

  12:             GetRepositoryCollectionInstance("sampleData");

  13:     }

  14: }

The idea is for developers to define what the repository will look like and where the data is for each “collection”.  The RepositoryBase contains a method SaveChanges which uses reflection to find the dirty collections in the repository and call their, internal, SaveChanges method.

All data is stored in a delimited fashion within the isolated storage file.  The delimiter used is “**,**”, which attempts to be unique enough to where conflicts should not arise.  Using this technique gives the lines a column look and feel.  To map these columns we use the custom attribute: DataColumnAttribute.  This attributes chief responsibility is to store the index the property maps to.  An example entity is shown below:

   1: public class StorageItem : EntityBase

   2: {

   3:     [DataColumn(0)]

   4:     public string TwitterHandle { get; set; }


   6:     [DataColumn(1)]

   7:     public string AccessCode { get; set; }

   8: }

This essentially says the value in position 0 is the TwitterHandle, at position 1 it is the AccessCode.  The assignment is done through reflection and is one of the areas that I may make a change to remove reflection for performance gains.  However, the idea is that IsolatedStorage will not contain that much data, so speed is not always going to be an issue.

The biggest issue with this code at the moment is how to handle the loading of the existing file.  For the moment, when the collection is instantiated the data file behind it is loaded in if it is determined it hasn’t been loaded already.  This means, this will happen whenever you instantiate a new instance.

This also has the potential to run into threading issues, but this code is still in its very early stages.  Also, one has to remember the user is not really going to query the file like they would a database table, or even an XML file.  The structure set within the IsolatedStorageFile is loose, at best.

Goals moving forward are the continued removal of unnecessary reflective code as well as the establishing consistent idea for data access including how to load the data ahead of time in a timely fashion.

The current code and the accompanying example project are downloadable below.


Leave a Reply

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

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

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s