In Memory Repository

Wednesday, July 13, 2011 9:28 AM

I mentioned to a buddy the in memory repository I've used on a few projects. He asked me to share so here it is...

Two things to note. The Entity base class has a single property on it called Id. And remember that the InMemoryRepository isn't transactional so everything done is immediate and submitting changes or rolling back on the unit of work has no effect. You could certainly add this behavior of course, but as-is doesn't bother with it.

public interface IRepository
{
  T Get<T>(int id) where T : Entity;
  T Get<T>(Expression<Func<T, bool>> predicate) where T : Entity;

  IQueryable<T> Find<T>() where T : Entity;
  IQueryable<T> Find<T>(Expression<Func<T, bool>> predicate) where T : Entity;

  T Add<T>(T entity) where T : Entity;
  T Remove<T>(T entity) where T : Entity;
}

public class InMemoryRepository : IRepository
{
  public InMemoryRepository()
  {
  }

  public InMemoryRepository(bool clear)
  {
    if (clear)
      _lists.Clear();
  }

  public T Get<T>(int id) where T : Entity
  {
    return Get<T>(x => x.Id == id);
  }

  public T Get<T>(Expression<Func<T, bool>> predicate) where T : Entity
  {
    return Find<T>().SingleOrDefault(predicate);
  }

  public IQueryable<T> Find<T>() where T : Entity
  {
    return ListFor<T>().AsQueryable();
  }

  public IQueryable<T> Find<T>(Expression<Func<T, bool>> predicate) where T : Entity
  {
    return Find<T>().Where(predicate);
  }

  public T Add<T>(T entity) where T : Entity
  {
    ListFor<T>().Add(entity);
    return entity;
  }

  public T Remove<T>(T entity) where T : Entity
  {
    ListFor<T>().Remove(entity);
    return entity;
  }

  /**********************************************************************/
  /**********************************************************************/

  private static readonly IDictionary<Type, object> _lists = new Dictionary<Type, object>();
  private static readonly object _lockObject = new object();

  private static IList<T> ListFor<T>()
  {
    var type = typeof(T);

    if (!_lists.ContainsKey(type))
    {
      lock (_lockObject)
      {
        if (!_lists.ContainsKey(type))
        {
          Type listType = typeof(List<>).MakeGenericType(type);
          _lists[type] = Activator.CreateInstance(listType);
        }
      }
    }

    return (IList<T>)_lists[type];
  }
}
Tags: .net