I've been trying to put together a tiered app but it feel very clunky. All the examples and tutorials I've seen are extremely basic and don't seem to hold up when applied to my project.
Issue 1) I believe I have the DAL how I want it but the BLL and API layers require me to pass the datacontext all the way down from the UI when it shouldn't reference the data layer.
Issue 2) I have 2 base classes for all my data models, BaseModel and BaseNameModel. I don't want to have to create a specific Repo for every single DB object and implement the exact same Search() method over and over. So I tried to use a generic one and only create specific ones when I need to override. This forced me to move my Search method to a new API layer and remember which entities I had to create specific implementations for.
I know the overall design is backwards but I can't figure out why.
*** Model layer ***
// Base class for all DB Models
public class BaseModel
{
int Id {get; set;}
}
// 95% of DB Models have this property
public class BaseNameModel
{
int Id {get; set;}
string Name {get; set;}
}
*** DAL ***
// Context Interface
public interface IDataContext
{
T GetById<T>(int Id, params string[] joins) where T : BaseModel;
IQueryable<T> Get<T>(params string[] joins) where T : BaseModel;
IQueryable<T> Get<T>(Expression<Func<T, bool>> where = null, params string[] joins) where T : BaseModel;
}
// Entity Framework Context
public class EFContext : DbContext, IDataContext
{
public EFContext() : base()
{
Database.SetInitializer<EFContext>(null);
}
public DbSet<User> Users { get; set; }
public DbSet<School> Schools { get; set; }
T GetById<T>(int Id, params string[] joins) where T : BaseModel
{
var rv = Set<T>().Where(where);
}
IQueryable<T> Get<T>(params string[] joins) where T : BaseModel
{
var rv = Set<T>();
foreach (string join in joins)
rv.Include(join);
}
IQueryable<T> Get<T>(Expression<Func<T, bool>> where = null, params string[] joins) where T : BaseModel
{
var rv = Set<T>().Where(where);
foreach (string join in joins)
rv.Include(join);
}
}
// Mock Context
public class MockContext : IDataContext
{
T GetById<T>(int Id, params string[] joins) where T : BaseModel
{
// Return IList<T>.Where(m => m.id == Id);
}
IQueryable<T> Get<T>(params string[] joins) where T : BaseModel
{
// Return IList<T>;
}
IQueryable<T> Get<T>(Expression<Func<T, bool>> where = null, params string[] joins) where T : BaseModel
{
// Return IList<T>.Where(where);
}
}
*** BLL ***
// BLL Repo using IDataContext
public class Repo<T>
{
private IDataContext _context;
public Repo(IDataContext dataContext)
{
_context = dataContext;
}
public IQueryable<T> Get(params string[] joins)
{
return _context.Get<T>(joins);
}
}
*** API layer ***
// Generic API-ish layer
public class GenericAPI<T> where T : BaseNameModel
{
Repo<T> repo = new Repo<T>
public virutal BaseSearchResult Search(BaseSearchCriteria searchModel)
{
return repo.Get(e => e.Name == searchModel.Name);
// convert results to BaseSearchResult and return
}
}
// Entity Specific API-ish layer
public class UserApi : GenericAPI<User>
{
public virutal UserSearchResult Search(UserSearchCriteria searchModel)
{
return repo.Get(e => e.Name == searchModel.Name && e.Grade == searchModel.Grade);
// convert results to UserSearchResult and return
}
}
Aucun commentaire:
Enregistrer un commentaire