【问题标题】:Inject a repository which has Generic as well as Concrete Implementation to a controller将具有通用和具体实现的存储库注入控制器
【发布时间】:2019-11-12 19:13:56
【问题描述】:

我正在创建一个通用存储库,但对于某些实体,我还需要通用存储库未提供的功能。我有一个接口 IGenericRepository 和具体实现作为具有基本 CRUD 操作的 GenericRepository。此外,我有一个 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,我只会获得 genericrepository 功能。如果我想要不包含在 genericRepository 中的 Student 存储库的功能,我必须注入 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 
        }  



 }


有没有更好的方法来做到这一点?像这样注入两个上下文相同但编码不同的对象感觉不对。

【问题讨论】:

    标签: c# generics dependency-injection .net-core repository


    【解决方案1】:

    你可以让IStudentRepository扩展IGenericEntityRepository&lt;T&gt;

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

    现在注入IStudentRepository 应该足以使用所有功能了。

    【讨论】:

    • 会工作,但是我拥有的通用存储库,以及我已经编写的它的基本 CRUD 功能,将在具体存储库中到处复制。
    • @PrajwolCE 不,它不会被复制。您已经从 GenericRepository 继承,这意味着您已经在通用接口上实现了方法。试试看,你会看到的。
    • 是的,你是对的,我一直在扩展 Concrete StudeRepository 并且困惑为什么它在我应该扩展它的 Inferface 时不起作用! :) 非常非常感谢,从早上起就一直在拉我的头发!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-27
    • 1970-01-01
    • 2018-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多