I have pointed here several times before – but it’s so nice.
It’s an implementation of the Repository Pattern using generics, that will minimize your code in a very nice way. I am sure that the FindAll can be refined into something very nice with LINQ, that allows you to send a specification criteria or so.
Here is my implementation that uses a common interface (IBaseEntity) for all my entities. It basically has an ID, so that the abstract implementation can use it as a key:
namespace Marcusoft.SprintPlannerHelper.Repositories
{
/// \<summary\>
/// A generic repository interface that dictates all the methods
that a repository should map to
/// \</summary\>
/// \<typeparam name="T"\>the type of the interface\</typeparam\>
public interface IRepository<T> where T :IBaseEntity
{
T GetById(Guid id);
IList<T> FindAll();
void Add(T entity);
void Remove(T entity);
}
public abstract class Repository<T> : IRepository<T> where T : IBaseEntity
{
protected readonly Dictionary<Guid, T> dictionary = new Dictionary<Guid, T>();
public T GetById(Guid id)
{
return dictionary\[id\];
}
public IList<T> FindAll()
{
return new List<T>(dictionary.Values);
}
public void Add(T entity)
{
dictionary.Add(entity.ID, entity);
}
public void Remove(T entity)
{
dictionary.Remove(entity.ID);
}
}
public class ProductRepositoryFake: Repository<Product>, IProductRepository
{
/// \<summary\>
/// Default constructor that fills the repository with some test data
/// \</summary\>
public ProductRepositoryFake()
{
// Add the products from the test data-class
foreach (var p in TestData.GetTestProductList())
{
dictionary.Add(p.ID, p);
}
}
}
I implemented it and wrote this with Albert sleeping on my chest. Just imagine if all programming sessions were so peaceful.