EntityFramework Repositories drives from an Interface and abstract class : how to use dependency inject on ASP.NET MVC
Ok, let me break down what I have been trying to do :
First of all here is the abstract
generic repository of mine :
public abstract class Repository<T, C> where T : class where C : DbContext, new() {
private C _entities = new C();
public IQueryable<T> FindBy(Expression<Func<T, bool>> predicate) {
IQueryable<T> query = _entities.Set<T>().Where(predicate);
return query;
}
public void Add(T entity) {
_entities.Set<T>().Add(entity);
}
public void Delete(T entity) {
_entities.Set<T>().Remove(entity);
}
public void Edit(T entity) {
_entities.Entry(entity).State = System.Data.EntityState.Modified;
}
public void Save() {
_entities.SaveChanges();
}
}
Also, here is an interface which I will use for my AccommPropertyWebDetailRepository
repository class
:
public interface IAccommPropertyWebDetailRepository {
IQueryable<AccommPropertyWebDetail> GetAll(ApprovalStatus approvalstatus = ApprovalStatus.All);
AccommPropertyWebDetail GetSingle(int accommPropertyWebDetailId, ApprovalStatus approvalstatus = ApprovalStatus.All);
AccommPropertyWebDetail GetSingleByAccommPropertyId(int accommPropertyId, ApprovalStatus approvalstatus = ApprovalStatus.All);
}
And the below one is my AccommPropertyWebDetailRepository
class :
public class AccommPropertyWebDetailRepository : Repository<AccommPropertyWebDetail, ReservationHubEntities>, IAccommPropertyWebDetailRepository {
ReservationHubEntities _entities = new ReservationHubEntities();
public IQueryable<AccommPropertyWebDetail> GetAll(ApprovalStatus approvalstatus = ApprovalStatus.All) {
IQueryable<AccommPropertyWebDetail> query = _entities.AccommPropertyWebDetails;
switch (approvalstatus) {
case ApprovalStatus.Approved:
query = query.Where(x => (x.AccommProperty.IsApproved == true) && (x.AccommProperty.IsLockedForView == false));
break;
case ApprovalStatus.NotApproved:
query = query.Where(x => (x.AccommProperty.IsApproved == false) || (x.AccommProperty.IsLockedForView == true));
break;
}
return query;
}
public AccommPropertyWebDetail GetSingle(int accommPropertyWebDetailId, ApprovalStatus approvalstatus = ApprovalStatus.All) {
var query = GetAll(approvalstatus).First(x => x.AccommPropertyWebDetailID == ac开发者_运维知识库commPropertyWebDetailId);
return query;
}
public AccommPropertyWebDetail GetSingleByAccommPropertyId(int accommPropertyId, ApprovalStatus approvalstatus = ApprovalStatus.All) {
var query = GetAll(approvalstatus).Single(x => x.AccommPropertyID == accommPropertyId);
return query;
}
}
So everything has been fine so far (according to me but I am not sure what I am missing).
The real problem I have is on the ASP.NET MVC Web application side.
Let's assume that my controller class starts as follows :
public AccommPropertyController(
IAccommPropertyPictureRepository accommpropertypicturerepo) {
_accommpropertypicturerepo = accommpropertypicturerepo;
}
private readonly IAccommPropertyPictureRepository _accommpropertypicturerepo;
And for dependency injection, I have the following code (I am using Ninject for Dependency Injection) :
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel) {
kernel.Bind<IAccommPropertyPictureRepository>().
To<AccommPropertyPictureRepository>();
}
So, where is Repository<T, C>
abstract class supposed to fit in here?
Because, I didn't directly use AccommPropertyPictureRepository
inside my controller and only used IAccommPropertyPictureRepository
interface, my controller doesn't know anything about Repository<T, C>
abstract class.
Any known ways of dealing with this annoying issue?
UPDATE 1
So, now after @Darin's suggestion, I have following interface
public interface IRepository<T, C> where T : class where C : DbContext {
IQueryable<T> FindBy(Expression<Func<T, bool>> predicate);
void Add(T entity);
void Delete(T entity);
void Edit(T entity);
void Save();
}
And my abstract class is as follows :
public abstract class Repository<T, C> : IRepository<T, C> where T : class where C : DbContext, new() {
private C _entities = new C();
public IQueryable<T> FindBy(Expression<Func<T, bool>> predicate) {
IQueryable<T> query = _entities.Set<T>().Where(predicate);
return query;
}
public void Add(T entity) {
_entities.Set<T>().Add(entity);
}
public void Delete(T entity) {
_entities.Set<T>().Remove(entity);
}
public void Edit(T entity) {
_entities.Entry(entity).State = System.Data.EntityState.Modified;
}
public void Save() {
_entities.SaveChanges();
}
}
Can't figure the rest of it out.
UPDATE 2
Now I have figured something out as well. Here is IAccommPropertyPictureRepository
interface :
public interface IAccommPropertyPictureRepository<T, C> : IRepository<T, C> where T : class where C : DbContext {
IQueryable<AccommPropertyPicture> GetAll(ApprovalStatus approvalstatus = ApprovalStatus.All);
IQueryable<AccommPropertyPicture> GetAll(int accommPropertyId, ApprovalStatus approvalstatus = ApprovalStatus.All);
AccommPropertyPicture GetSingle(int accommPropertyPictureId, ApprovalStatus approvalstatus = ApprovalStatus.All);
AccommPropertyPicture GetSingle(Guid accommPropertyPictureGUID, ApprovalStatus approvalstatus = ApprovalStatus.All);
}
and here is the AccommPropertyPictureRepository
class :
public class AccommPropertyPictureRepository : Repository<AccommPropertyPicture, ReservationHubEntities>, IAccommPropertyPictureRepository<AccommPropertyPicture, ReservationHubEntities> {
ReservationHubEntities _entities = new ReservationHubEntities();
public IQueryable<AccommPropertyPicture> GetAll(ApprovalStatus approvalstatus = ApprovalStatus.All) {
IQueryable<AccommPropertyPicture> query = _entities.AccommPropertyPictures;
switch (approvalstatus) {
case ApprovalStatus.Approved:
query = query.Where(x => (x.AccommProperty.IsApproved == true) && (x.AccommProperty.IsLockedForView == false));
break;
case ApprovalStatus.NotApproved:
query = query.Where(x => (x.AccommProperty.IsApproved == false) || (x.AccommProperty.IsLockedForView == true));
break;
}
return query;
}
public IQueryable<AccommPropertyPicture> GetAll(int accommPropertyId, ApprovalStatus approvalstatus = ApprovalStatus.All) {
var query = GetAll(approvalstatus).Where(x => x.AccommPropertyID == accommPropertyId);
return query;
}
public AccommPropertyPicture GetSingle(int accommPropertyPictureId, ApprovalStatus approvalstatus = ApprovalStatus.All) {
var query = GetAll(approvalstatus).First(x => x.AccommPropertyPictureID == accommPropertyPictureId);
return query;
}
public AccommPropertyPicture GetSingle(Guid accommPropertyPictureGUID, ApprovalStatus approvalstatus = ApprovalStatus.All) {
var query = GetAll(approvalstatus).First(x => x.AccommPropertyPictureGUID == accommPropertyPictureGUID);
return query;
}
}
I have a successful build now. Should Ninject
stuff stay unchanged? I think I only need to change some of the code from my controller constructor, right?
One possibility would be to have a base IRepository<T, C>
interface containing all the necessary operations and which will be implemented by the Repository<T, C>
abstract class as well as by the IAccommPropertyWebDetailRepository
interface.
精彩评论