EntityFramework Repositories управляет интерфейсом и абстрактным классом: как использовать внедрение зависимостей в ASP.NET MVC - PullRequest
2 голосов
/ 30 сентября 2011

Хорошо, позвольте мне разбить то, что я пытался сделать:

Прежде всего, вот мой общий репозиторий 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.NET MVC.

Давайте предположим, что мой класс контроллера начинается следующим образом:

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

Итак, теперь после предложения @ Дарина у меня есть 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 вещи остаться без изменений?Я думаю, что мне нужно только изменить часть кода из моего конструктора контроллера, верно?

1 Ответ

3 голосов
/ 30 сентября 2011

Одной из возможностей может быть базовый интерфейс IRepository<T, C>, содержащий все необходимые операции и который будет реализован абстрактным классом Repository<T, C>, а также интерфейсом IAccommPropertyWebDetailRepository.

...