using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
namespace COA.EnterpriseServices.DataAccess
{
///
/// 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
}
}