using System; using System.Collections.Generic; using System.Linq; using System.Xml.Linq; namespace Model.Data { public interface IProductRepository { Category GetCategoryById(int id); Category GetCategoryByShortName(string name); IEnumerable GetCategories(); Product GetProductById(int id); Product GetProductByShortName(string name); IEnumerable GetProducts(); IEnumerable GetProductsByCategory(int categoryId); } public class ProductRepository : IProductRepository { #region Properties private readonly XDocument data; private static string _DataFilePath = string.Format("{0}/App_Data/ProductData.xml", AppDomain.CurrentDomain.BaseDirectory); protected static string DataFilePath { get { return _DataFilePath; } set { _DataFilePath = value; } } #endregion #region Constructors public ProductRepository() : this(XDocument.Load(DataFilePath)) { } public ProductRepository(XDocument xdoc) { data = xdoc; } #endregion public Category GetCategoryById(int id) { if (id == Category.All.ID) return Category.All; return (from c in data.Descendants("Category") where c.Attribute("ID") == id select CreateCategoryFromXElement(c)).FirstOrDefault(); } public Category GetCategoryByShortName(string name) { if (string.IsNullOrEmpty(name)) return null; if (name.Equals(Category.All.ShortName, StringComparison.OrdinalIgnoreCase)) return Category.All; return (from c in data.Descendants("Category") where c.Attribute("ShortName").Equals(name, StringComparison.OrdinalIgnoreCase) select CreateCategoryFromXElement(c)).FirstOrDefault(); } public IEnumerable GetCategories() { var categories = (from c in data.Descendants("Category") select CreateCategoryFromXElement(c)).ToList(); // Add the "All" meta-category categories.Insert(0, Category.All); return categories; } public Product GetProductById(int id) { return (from p in data.Descendants("Product") where p.Attribute("ID") == id select CreateProductFromXElement(p)).FirstOrDefault(); } public Product GetProductByShortName(string name) { return (from p in data.Descendants("Product") where p.Attribute("ShortName").Equals(name, StringComparison.OrdinalIgnoreCase) select CreateProductFromXElement(p)).FirstOrDefault(); } public IEnumerable GetProducts() { return (from p in data.Descendants("Product") select CreateProductFromXElement(p)).AsEnumerable(); } public IEnumerable GetProductsByCategory(int categoryId) { if (categoryId == Category.All.ID) return GetProducts(); return (from p in data.Descendants("Product") where p.Attribute("CategoryID") == categoryId select CreateProductFromXElement(p)).AsEnumerable(); } #region Helpers protected static Category CreateCategoryFromXElement(XElement el) { return new Category { ID = el.Attribute("ID"), Name = el.Attribute("Name"), ShortName = el.Attribute("ShortName") }; } protected static Product CreateProductFromXElement(XElement el) { return new Product { ID = el.Attribute("ID"), CategoryID = el.Attribute("CategoryID"), Name = el.Attribute("Name"), ShortName = el.Attribute("ShortName"), Description = el.Element("Description").Value, Manufacturer = el.Attribute("Manufacturer"), ImageUrl = el.Attribute("ImageUrl"), UnitPrice = el.Attribute("UnitPrice"), UnitsInStock = el.Attribute("UnitsInStock") }; } #endregion } public static class XLinqExtensions { public static T Value(this XElement element) { return Parse(element.Value); } public static T Attribute(this XElement element, string name) { var attribute = element.Attribute(name); return attribute != null ? Parse(attribute.Value) : default(T); } private static T Parse(string val) { var obj = Parse(val, typeof(T)); return obj != null ? (T)obj : default(T); } private static object Parse(string value, Type type) { object retVal = null; if (type == typeof(string)) retVal = value; else if (type == typeof(int)) { int tmpInt; Int32.TryParse(value, out tmpInt); retVal = tmpInt; } else if (type == typeof(double)) { double tmpDouble; Double.TryParse(value, out tmpDouble); retVal = tmpDouble; } return retVal; } } }