Using Isolated storage stores to create a MRU Manager

.Net has Isolated Storage Stores that can be used to read/write application settings. One example that is provided below is of the MRU (Most Recently Used) List

History:  Isolated Storage Stores:  
.Net provided Isolated storage to read and write common application settings like the MRU list  
in the following example.  It is called as "Isolated" stores because the running application need not know where the application settings file are stored. The path where these are stored is dependent on the scope of the store.



To use:  Create a the mruManager of type entity like below
   private static MRUManager<Portfolio> _mruManager = new MRUManager<Portfolio>("Portfolio", 10);
  To Add to MRU list     _mruManager.Add(newPortfolio);

Please note: Exception handling should be done to this code. Necessary comments are added to necessary sections.
The IsolatedStorageFlag for this example is just the assembly and the user and hence the path as mentioned in the comment.
//code
using System;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.IO;
using System.IO.IsolatedStorage;
using System.Xml.Serialization;

namespace Utilities
{
    /// <summary>
    /// MRU Mangaer
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class MRUManager<T>
    {
         /// <summary>
        ///
        /// </summary>
        private string _listName;
        /// <summary>
        ///
        /// </summary>
        private int _limit;
        /// <summary>
        ///
        /// </summary>
        private ObservableCollection<T> _list;

         /// <summary>
        /// Occurs when [list changed].
        /// </summary>
        public event EventHandler ListChanged;

         /// <summary>
        /// Initializes a new instance of the <see cref="MRUManager<T>"/> class.
        /// </summary>
        /// <param name="listName">Name of the list.</param>
        /// <param name="limit">The limit.</param>
        public MRUManager(string listName, int limit)
        {
             if (String.IsNullOrEmpty(listName))
             {
                 throw new ArgumentOutOfRangeException("listName", "name cannot be null or empty");
            }

            if (limit <= 0)
             {
                 throw new ArgumentOutOfRangeException("limit", "limit must be greater than zero.");
            }

            _listName = listName;
            _limit = limit;
             LoadFromDisk();
        }


        /// <summary>
        /// Gets the name of the list.
        /// </summary>
        /// <value>The name of the list.</value>
        public string ListName
        {
            get { return _listName; }
        }

        /// <summary>
        /// Gets the limit.
        /// </summary>
        /// <value>The limit.</value>
        public int Limit
        {
            get { return _limit; }
        }

        /// <summary>
        /// Gets the list.
        /// </summary>
        /// <value>The list.</value>
        public ReadOnlyCollection<T> List
        {
            get { return new ReadOnlyCollection<T>(_list); }
         }

        public void Add(T item)
        {
             if (_list.Contains(item))
            {
                _list.Remove(item);
            }
            _list.Insert(0, item);
             RemoveExtraItems();
        }

        /// <summary>
        /// Clears this instance.
        /// </summary>
        public void Clear()
        {
             _list.Clear();
        }

         /// <summary>
        /// Saves to disk.
        /// </summary>
        private void SaveToDisk()
        {
             try
            {
                 // Scope = User &   Assembly.
                 // store is a container of streams of the IsolatedStorageFile class.
                 using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForAssembly())
                 {
                     string fileName = "mruList_" + ListName;
                    IsolatedStorageFileStream stream;
                     if (store.GetFileNames(fileName).Length > 0)
                    {
                        stream = new IsolatedStorageFileStream(fileName, FileMode.Truncate, FileAccess.Write, store);
                     }
                      else
                    {
                        stream = new IsolatedStorageFileStream(fileName, FileMode.Create, FileAccess.Write, store);
                     }
                      using (stream)
                    {
                        XmlSerializer serializer = new XmlSerializer(typeof(ObservableCollection<T>));
                        serializer.Serialize(stream, _list);
                     }
                 }
            }
            catch (Exception e)
             {
                 //log "Unable to save MRU list to disk." along with e.
            }
        }

         /// <summary>
        /// Loads from disk.
        /// </summary>
        private void LoadFromDisk()
        {
            ObservableCollection<T> list = null;
            try
            {
                 //C:\Documents and Settings\[username]\Local Settings\Application Data\IsolatedStorage
                 using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForAssembly())
                 {
                     string fileName = "mruList_" + ListName;
                     if (store.GetFileNames(fileName).Length > 0)
                      {
                          using (IsolatedStorageFileStream stream = new
                            IsolatedStorageFileStream(fileName, FileMode.Open, FileAccess.Read, store))
                        {
                            XmlSerializer serializer = new XmlSerializer(typeof(ObservableCollection<T>));
                            list = serializer.Deserialize(stream) as ObservableCollection<T>;
                          }
                     }
                 }
             }
             catch (Exception e)
             {
                 //Log : "Unable to load MRU list from disk." along with e.
            }
            if (list == null) list = new ObservableCollection<T>();
            _list = list;
            _list.CollectionChanged
                += new NotifyCollectionChangedEventHandler(CollectionChangedHandler);
             RemoveExtraItems();
        }

         /// <summary>
        /// Removes the extra items.
        /// </summary>
        private void RemoveExtraItems()
        {
            if (_list.Count > Limit)
             {
                 for (int x = Limit; x < _list.Count; x++)
                 {
                      _list.RemoveAt(x);
                 }
             }
         }

         /// <summary>
        /// Collections the changed handler.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Collections.Specialized.NotifyCollectionChangedEventArgs"/> instance containing the event data.</param>
        private void CollectionChangedHandler(object sender, NotifyCollectionChangedEventArgs e)
         {
             SaveToDisk();
             if (ListChanged != null)
            {
                 ListChanged.Invoke(this, EventArgs.Empty);
             }
        }
    }
}
By [)ia6l0 iii   Popularity  (1341 Views)