I had a similar requirement in one of my projects. What I ended up doing is creating a DataAccesLayer (DAL) Cache base that I inherit in the DAL for each of my components. I have a separate caching class that holds the cache. Note that all my objects had ID and Name. You can tailor the base class however you need.
DAL Base Class:
public abstract class DALBaseCache<T>
{
public List<T> ItemList
{
get
{
List<T> itemList = DALCache.GetItem<List<T>>(typeof(T).Name + "Cache");
if (itemList != null)
return itemList;
else
{
itemList = GetItemList();
DALCache.SetItem(typeof(T).Name + "Cache", itemList);
return itemList;
}
}
}
/// <summary>
/// Get a list of all the Items
/// </summary>
/// <returns></returns>
protected abstract List<T> GetItemList();
/// <summary>
/// Get the Item based on the ID
/// </summary>
/// <param name="name">ID of the Item to retrieve</param>
/// <returns>The Item with the given ID</returns>
public T GetItem(int id)
{
return (from item in ItemList
where (int)item.GetType().GetProperty("ID").GetValue(item, null) == id
select item).SingleOrDefault();
}
/// <summary>
/// Get the Item based on the Name
/// </summary>
/// <param name="name">Name of the Item to retrieve</param>
/// <returns>The Item with the given Name</returns>
public T GetItem(string name)
{
return (from item in ItemList
where (string)item.GetType().GetProperty("Name").GetValue(item, null) == name
select item).SingleOrDefault();
}
}
Then my Caching Class which basically holds a dictionary of my queries
public static class DALCache
{
static Dictionary<string, object> _AppCache = new Dictionary<string, object>();
public static T GetItem<T>(string key)
{
if(_AppCache.ContainsKey(key))
{
return (T) _AppCache[key];
}
else
{
return default(T);
}
}
public static void SetItem(string key, object obj)
{
_AppCache.Add(key, obj);
}
}
And finally an implementation with a cached List. I use EF to get my CustomerType list and cache it for remainder of the Application life. You can change this as you need.
public class CustomerTypeDAL: DALBaseCache<CustomerType>
{
protected override List<CustomerType> GetItemList()
{
DBEntities entities = new DBEntities();
return Mapper.Map <List<CustomerType>>(entities.GetAllCustomerTypes().ToList());
}
}
Anywhere in your code you can use it as:
CustomerTypeDAL customerTypeDAL = new CustomerTypeDAL();
List<CustomerType> custTypes = customerTypeDAL.ItemList;
First time you call it, it will grab it from DB. After that it will go after cache.