using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; namespace COA.EnterpriseServices.DataAccess { public class DataAccessManager2 { private static readonly IDictionary enabledDataAccess = new Dictionary { #region Creditor ["COA.EnterpriseServices.DataAccess.Entities.Creditor"] = new[] { "COA.EnterpriseServices.DataAccess.QuickBase.QuickBaseDataAccess", "COA.EnterpriseServices.DataAccess.EntityFramework.EntityDataAccess" }, #endregion #region Client ["COA.EnterpriseServices.DataAccess.Entities.Client"] = new[] { "COA.EnterpriseServices.DataAccess.QuickBase.QuickBaseDataAccess", "COA.EnterpriseServices.DataAccess.EntityFramework.EntityDataAccess" } #endregion }; public ICollection Get(Expression> query) where T : class, IRecord { return Invoke>(d => d.Get(query)); } public T Get(int id) where T : class, IRecord { var item = Get(i => i.Id == id); if (item != null && item.Any()) { return item.FirstOrDefault(); } return default; } public bool Add(T item) where T : class, IRecord { return Invoke(d => d.Add(item)); } public bool Update(T item) where T : class, IRecord { item.Modified = DateTime.Now; return Invoke(d => d.Update(item)); } public bool Update(int id, Action update) where T : class, IRecord { var item = Get(id); update(item); return Update(item); } public ICollection Raw(string command, params object[] parameters) where T : class, IRecord { return Invoke>(d => d.Raw(command, parameters)); } private TResult Invoke(Func, TResult> func) where T : class, IRecord { var results = new List(); var dataAccessInstances = GetEnabledDataAccess(); foreach (var dataAccessInstance in dataAccessInstances) { results.Add(func(dataAccessInstance)); } // if the "EF" version invokes first, return that value return results.FirstOrDefault(r => r != null && !r.Equals(default(TResult))); } private ICollection> GetEnabledDataAccess() where T : class, IRecord { var type = typeof(T); // load data access based on active configuration return Dependencies.Container .GetAllInstances>() .Select(i => new { Instance = i, Type = i.GetType() }) .Where(i => enabledDataAccess.ContainsKey(type.FullName) && enabledDataAccess[type.FullName].Any(a => i.Type.FullName.StartsWith(a))) .OrderBy(i => i.Type.Name.StartsWith("QuickBase", StringComparison.OrdinalIgnoreCase)) .Select(i => i.Instance) .ToList(); } } /// /// Provides a wrapper around as well as additional convenience CRUD methods /// /// public class DataAccessManager where T : class, IRecord { private static readonly IDictionary enabledDataAccess = new Dictionary { #region Creditor ["COA.EnterpriseServices.DataAccess.Entities.Creditor"] = new[] { "COA.EnterpriseServices.DataAccess.QuickBase.QuickBaseDataAccess", "COA.EnterpriseServices.DataAccess.EntityFramework.EntityDataAccess" }, #endregion #region Client ["COA.EnterpriseServices.DataAccess.Entities.Client"] = new[] { "COA.EnterpriseServices.DataAccess.QuickBase.QuickBaseDataAccess", "COA.EnterpriseServices.DataAccess.EntityFramework.EntityDataAccess" } #endregion }; public bool Add(T item) { return Invoke(d => d.Add(item)); } public bool Update(T item) { item.Modified = DateTime.Now; return Invoke(d => d.Update(item)); } public bool Update(int id, Action update) { var item = Get(id); update(item); return Update(item); } public T Get(int id) { var item = Invoke(d => d.Get(i => i.Id == id)); if (item != null && item.Any()) { return item.FirstOrDefault(); } return default; } public ICollection Get(Expression> query) { return Invoke(d => d.Get(query)); } #region Private Methods private TResult Invoke(Func, TResult> func) { var results = new List(); var dataAccessInstances = GetEnabledDataAccess(); foreach (var dataAccessInstance in dataAccessInstances) { results.Add(func(dataAccessInstance)); } // if the "EF" version invokes first, return that value return results.FirstOrDefault(r => r != null && !r.Equals(default(TResult))); } private ICollection> GetEnabledDataAccess() { var type = typeof(T); // load data access based on active configuration return Dependencies.Container .GetAllInstances>() .Select(i => new { Instance = i, Type = i.GetType() }) .Where(i => enabledDataAccess.ContainsKey(type.FullName) && enabledDataAccess[type.FullName].Any(a => i.Type.FullName.StartsWith(a))) .OrderBy(i => i.Type.Name.StartsWith("QuickBase", StringComparison.OrdinalIgnoreCase)) .Select(i => i.Instance) .ToList(); } #endregion } }