I'm new to this Repository pattern and have seen lot of repository pattern + UoW implementations all over the internet and I'm not able to reach to a conclusion as to which of them is correct . After going through many links I've been able to implement one .
Considering the following points in mind
- It should satisfy SOLID principles
- Be testable
- Be independent of framework
- Be independent of DB
Here is the code of the implementation
Generic IRepository
public interface IRepository<T> where T : class
{
void Add(T entity);
void Update(T entity);
void Delete(T entity);
T GetByKey(object id);
}
RepositoryBase
public abstract class RepositoryBase<D, T> : IRepository<T> where T : class where D : BaseDbContext
{
private D dataContext;
private readonly IDbSet<T> dbSet;
protected IDbFactory<D> DbFactory
{
get;
private set;
}
protected D DbContext
{
get { return dataContext ?? (dataContext = DbFactory.Init()); }
}
protected RepositoryBase(IDbFactory<D> dbFactory)
{
DbFactory = dbFactory;
dbSet = DbContext.Set<T>();
}
#region Implementation
public virtual void Add(T entity)
{
dbSet.Add(entity);
}
public virtual void Update(T entity)
{
dbSet.Attach(entity);
DbContext.Entry(entity).State = EntityState.Modified;
}
public virtual void Delete(T entity)
{
dbSet.Remove(entity);
}
public T GetByKey(object id)
{
return dbSet.Find(id);
}
#endregion
}
IUnitofWork , UnitOfWork
public interface IUnitOfWork<D> where D : BaseDbContext
{
void Commit();
}
public class UnitOfWork<D> : IUnitOfWork<D> where D : BaseDbContext, new()
{
private readonly IDbFactory<D> dbFactory;
private D dbContext;
public UnitOfWork(IDbFactory<D> dbFactory)
{
this.dbFactory = dbFactory;
}
public D DbContext
{
get { return dbContext ?? (dbContext = dbFactory.Init()); }
}
public void Commit()
{
DbContext.SaveChanges();
}
}
IDBFactory ,DBFactory
public interface IDbFactory<D> where D : BaseDbContext
{
D Init();
}
public class DbFactory<D> : Disposable, IDbFactory<D> where D : BaseDbContext, new()
{
D dbContext;
public D Init()
{
return dbContext ?? (dbContext = new D());
}
protected override void DisposeCore()
{
if (dbContext != null)
dbContext.Dispose();
}
}
BaseDbContext
public abstract class BaseDbContext : DbContext
{
public BaseDbContext(string nameOrConnectionString) : base(nameOrConnectionString)
{
}
}
ProjectDbContext
public partial class ProjectDbContext : BaseDbContext
{
public ProjectDbContext()
: base("name=ProjectDbContext")
{
Database.SetInitializer<ProjectDbContext>(null);
}
}
EXAMPLE USAGE
Controller
public class StudentsController : BaseController
{
private IStudentBusiness objstudentbusiness;
public StudentsController(IStudentBusiness rstudentbusiness)
{
objstudentbusiness = rstudentbusiness;
}
public JsonResult LoadStudents()
{
var data = objstudentbusiness.ListStudents();
var jsonResult = Json(data, JsonRequestBehavior.AllowGet);
return jsonResult;
}
}
IStudentBAL,StudentBAL
public interface IStudentBAL
{
void SaveStudent(StudentDto student);
List<StudentDto> ListStudents();
}
public class StudentBAL : BusinessBase, IStudentBAL
{
private readonly IStudentRepository objStudentRepository;
private readonly IUnitOfWork<ProjectDbContext> objIUnitOfWork;
public StudentBAL(IStudentRepository rIStudentRepository, IUnitOfWork<ProjectDbContext> rIUnitOfWork)
{
try
{
objStudentRepository = rIStudentRepository;
objIUnitOfWork = rIUnitOfWork;
}
catch (Exception ex)
{
Log.Error(ex);
}
}
public List<StudentDto> ListStudents()
{
try
{
var tusrs = objStudentRepository.ListStudents() ?? new List<StudentDto>();
return tusrs;
}
catch (Exception ex)
{
Log.Error(ex);
}
return new List<StudentDto>();
}
}
IStudentRepository,StudentRepository
public interface IStudentRepository
{
void SaveStudent(Student Student);
StudentDto GetStudentByName(StudentDto Studentname);
Student GetStudentByID(int Studentid);
List<StudentDto> ListStudents();
}
public class StudentRepository : RepositoryBase<ProjectDbContext, Student>, IStudentRepository
{
public StudentRepository(IDbFactory<ProjectDbContext> dbFactory) : base(dbFactory)
{
}
public List<StudentDto> ListStudents()
{
var students = (from t in DbContext.Students
select new StudentDto
{
// all the required properties
}).ToList();
return students;
}
}
- Dependency Injection is done using AutoFac
- Code for logging is omitted
I am asking if this seems like a good implementation or am I missing anything?
I would appreciate any feedback on my implementation you can offer regarding correctness, efficiency, and any suggestions. So here are my questions
- Is this loosely coupled ?
- Is it having any leaky abstraction and why ?
- What needs to be done to switch from EF to MySQL db and how much effort would it require to implement the changes?
- Is this pattern breaking any of the SOLID princples ,Law or Demeter or any Object Oriented laws?
- Does this pattern have any code redundancies which are not required ?
- How this architecture using EF would scale with a project containing more than 100+ domain entities and with each entity having at least more than 10 fields . Is it going to be maintenance nightmare later on?
All criticisms greatly appreciated !!
Aucun commentaire:
Enregistrer un commentaire