Skip to content

Instantly share code, notes, and snippets.

@ScottKaye
Created November 30, 2016 02:02
Show Gist options
  • Save ScottKaye/385a99bf92457e6f414ca6354212fd6f to your computer and use it in GitHub Desktop.
Save ScottKaye/385a99bf92457e6f414ca6354212fd6f to your computer and use it in GitHub Desktop.
/// <summary>
/// An in-memory repository of T.
/// </summary>
/// <typeparam name="T">Type of entities to emulate.</typeparam>
public class FakeRepository<T> : IRepository<T>
where T : class
{
private readonly PropertyInfo _key;
private readonly Dictionary<int, T> _entities;
public FakeRepository()
{
_key = GetIdProperty();
if (_key.PropertyType != typeof(int))
{
throw new NotSupportedException("Cannot fake entities where the key is not an int.");
}
_entities = new Dictionary<int, T>();
}
public void Create(T entity) => _entities.Add((int)_key.GetValue(entity), entity);
public void Delete(int? id) => _entities.Remove(id.Value);
public void Delete(T entity) => _entities.Remove((int)_key.GetValue(entity));
public void Dispose() => _entities.Clear();
public T Find(int? id)
{
T obj = default(T);
_entities.TryGetValue(id.Value, out obj);
return obj;
}
public IQueryable<T> GetAll() => _entities.Values.AsQueryable();
public void Update(T entity) => _entities[(int)_key.GetValue(entity)] = entity;
/// <summary>
/// Get the Id property of an entity. This is roughly the same thing that Entity Framework does when not provided with a [Key] override.
/// </summary>
/// <see cref="https://github.com/mono/entityframework/blob/70998a4be0ed566ad3f21d6c5a51016b7c16f9bd/src/EntityFramework/ModelConfiguration/Conventions/Edm/IdKeyDiscoveryConvention.cs#L22"/>
/// <param name="obj">Object from which to get the key.</param>
/// <returns>Property info for the key, or null if a key was not found.</returns>
private PropertyInfo GetIdProperty()
{
var name = typeof(T).Name;
var primitiveProperties = typeof(T).GetProperties().Where(p => p.PropertyType.IsPrimitive);
return (from p in primitiveProperties
where p.Name.Equals("Id", StringComparison.OrdinalIgnoreCase)
|| p.Name.Equals(name + "Id", StringComparison.OrdinalIgnoreCase)
select p).Single();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment