Внедрить в контроллер репозиторий, имеющий как общие, так и конкретные реализации - PullRequest
2 голосов
/ 02 июля 2019

Я делаю общий репозиторий, но для некоторых объектов мне также нужны функциональные возможности, не предоставляемые общим репозиторием.У меня есть интерфейс IGenericRepository и конкретная реализация как GenericRepository с основными операциями CRUD.Кроме того, у меня есть studentRepository, который использует общий репозиторий, но также имеет собственные функции, независимые от общего репозитория, для которого у меня есть интерфейс с именем IStudentRepository.

Вот пример кода:

  public interface IGenericEntityRepository<T> 
  {
        Delete(T entity);

        T Get(int id);

        IEnumerable<T> GetAll();

        Add(T entity);

        Update(T entity);
  }


public class GenericEntityRepository<T> : IGenericEntityRepository<T> where T : class
 {

        protected readonly ApplicationDbContext _applicationDbContext;

        public GenericEntityRepository(ApplicationDbContext applicationDbContext)
        {
            this._applicationDbContext = applicationDbContext;
        }

     //Generic Repository Implementations....
 }


 public interface IStudentRepository
 {
      string GetFullName(Student student)
      double GetGpa(Student student)
 }

 public class StudentRepository: GenericRepository<Student>, IStudentRepository
 {
    public StudentRepository(ApplicationDbContext applicationDbContext) : base(applicationDbContext)
    {}

    //IStudentRepository functions' implementations...
 }

Now I need to inject this StudentRepository to my StudentsController 

 public class StudentsController : Controller
 {
        private readonly IGenericEntityRepository<Student> _genericStudentRepository;

        public StudentsController(IGenericEntityRepository<Student> _genericStudentRepository)
        {
            this._genericStudentRepository = genericRepository;           
        }

        public void testAccessibility() 
        {
             this._genericStudentRepository.GetAll() //valid call
             this._genericStudentRepository.GetAllGpa() //invalid Call 
             ***As expected cause IGenericEntityRepository doesn't have that ***function 
        }  

 }

Как вы можете видеть здесь, если я вставляю IGenericEntityRepository, я получаю только общие функции репозитория.Если я хочу, чтобы функции репозитория Student не были включены в genericRepository, я должен внедрить IGenericEntityRepository и IStudentRepository, как показано ниже, и наоборот.

 public class StudentsController : Controller
 {
        private readonly IGenericEntityRepository<Student> _genericStudentRepository;
        private readonly IStudentRepository _studentsRepository;

        public StudentsController(IGenericEntityRepository<Student> _genericStudentRepository, IStudentRepository studentsRepository)
        {
            this._genericStudentRepository = genericRepository;
            this.__studentsRepository = studentsRepository;
        }

  public void testAccessibility() 
        {
             this._genericStudentRepository.GetAll() //valid call
             this._studentsRepository.GetAllGpa() //valid call 
        }  



 }


Есть ли лучший способ сделать это?Неправильно вводить два контекстно одинаковых, но кодирующих разные объекты, подобные этому.

1 Ответ

3 голосов
/ 02 июля 2019

Вы можете иметь IStudentRepository extension IGenericEntityRepository<T>:

public interface IStudentRepository : IGenericEntityRepository<Student> 
{
      string GetFullName(Student student)
      double GetGpa(Student student)
}

Теперь инъекции IStudentRepository должно быть достаточно для использования всех функций.

...