using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic;
using System.Linq.Expressions;
using System.Reflection;
using System.ComponentModel;
namespace EPS.Common.Repositories
{
///
/// An implementation of IRepository.
///
/// The type that the repository will contain.
public class Repository : IRepository where TModel : IModel, new()
{
private int _idcounter = 0;
///
/// Gets a count of the number of models in the repository.
///
/// The number of models in the repository.
public int Count
{
get
{
return _models.Count;
}
}
private List _models = new List();
///
/// Doesn't really find anything, just returns everything in the repository.
///
/// The contents of the repository.
public IEnumerable FindAll()
{
return _models;
}
///
/// Finds an instance of TModel by id.
///
/// The id of the TModel instance to find.
///
/// TModel if the id is found, otherwise null.
///
public TModel Find(int id)
{
foreach(TModel m in this._models)
{
if (m.ID == id)
return m;
}
return default(TModel);
}
///
/// Inserts the instance if it does not already exist, otherwise updates the existing one.
///
/// The model to save.
public void Save(TModel model)
{
TModel existing = default(TModel);
if (_models.Count > 0)
existing = this.Find(model.ID);
if (existing == null)
{
_idcounter += 1;
model.ID = _idcounter;
_models.Add(model);
return;
}
//copy all of the writable values from the updated model to the existing model
//excluding ID because we'd always be setting it to zero otherwise.
foreach(PropertyInfo property in typeof(TModel).GetProperties())
{
if (!property.CanWrite && property.Name != "ID")
continue;
property.SetValue(existing, property.GetValue(model, null), null);
}
}
///
/// Deletes the specified model from the repository.
///
/// The model to be removed.
public void Delete(TModel model)
{
_models.RemoveAll(m => { return m.ID == model.ID; });
}
///
/// Orders the list by property name.
///
/// Name of the property.
/// The sort direction.
///
/// A new list sorted by property name in the order indicated by the sortDirection.
///
public IEnumerable OrderBy(string propertyName, Sort sortDirection)
{
if (String.IsNullOrEmpty(propertyName))
throw new ArgumentNullException("propertyName");
return _models.AsQueryable().OrderBy(propertyName + " " + sortDirection.ToString());
}
///
/// Orders the list by property name.
///
/// Values to indicate sorting properties.
/// eg, new { Property = "FirName", SortAscending = true }
///
public IEnumerable OrderBy(object values)
{
if (values == null) throw new ArgumentNullException("values");
string propertyName = String.Empty;
Sort sortDirection = Sort.Ascending;
PropertyDescriptorCollection props = TypeDescriptor.GetProperties(values);
foreach (PropertyDescriptor prop in props)
{
switch (prop.Name)
{
case "Property":
propertyName = prop.GetValue(values).ToString();
break;
case "SortAscending":
sortDirection = Convert.ToBoolean(prop.GetValue(values)) ? Sort.Ascending : Sort.Descending;
break;
}
}
return OrderBy(propertyName, sortDirection);
}
}
}