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); } } }