实体框架存储库驱动从一个接口和抽象类:如何使用依赖注入在ASP.净MVC

本文关键字:何使用 抽象类 依赖 注入 MVC ASP 接口 一个 存储 框架 实体 | 更新日期: 2023-09-27 18:10:12

好的,让我来详细说明一下我一直在做的事情:

首先这里是我的abstract通用存储库:

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();
    }
}

另外,这里是一个接口,我将使用我的AccommPropertyWebDetailRepository存储库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);
}

下面是我的AccommPropertyWebDetailRepository类:

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 == accommPropertyWebDetailId);
            return query;
        }
        public AccommPropertyWebDetail GetSingleByAccommPropertyId(int accommPropertyId, ApprovalStatus approvalstatus = ApprovalStatus.All) {
            var query = GetAll(approvalstatus).Single(x => x.AccommPropertyID == accommPropertyId);
            return query;
        }
}

所以到目前为止一切都很好(根据我,但我不确定我错过了什么)。

真正的问题是在ASP上。asp.net MVC Web应用端。

让我们假设我的控制器类开始如下:

public AccommPropertyController(
    IAccommPropertyPictureRepository accommpropertypicturerepo) {
    _accommpropertypicturerepo = accommpropertypicturerepo;
}
private readonly IAccommPropertyPictureRepository _accommpropertypicturerepo;

对于依赖注入,我有以下代码(我使用Ninject进行依赖注入):

/// <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>();
}  

那么,Repository<T, C>抽象类应该适合在这里吗?

因为我没有在控制器内部直接使用AccommPropertyPictureRepository,只使用IAccommPropertyPictureRepository接口,所以控制器不知道Repository<T, C>抽象类的任何内容。

有什么已知的方法来处理这个恼人的问题吗?

更新1

所以,现在在@Darin的建议下,我有以下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();
}

我的抽象类如下:

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();
    }
}

我想不出剩下的。

更新2

现在我也弄明白了一些事情。以下是IAccommPropertyPictureRepository接口:

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);
}

这是AccommPropertyPictureRepository类:

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;
    }
}

我现在有一个成功的构建。Ninject的东西应该保持不变吗?我想我只需要改变控制器构造函数中的一些代码,对吧?

实体框架存储库驱动从一个接口和抽象类:如何使用依赖注入在ASP.净MVC

一种可能性是有一个包含所有必要操作的基本IRepository<T, C>接口,它将由Repository<T, C>抽象类和IAccommPropertyWebDetailRepository接口实现。