【问题标题】:Extending GenericRepository to be used in a Controller [closed]扩展 GenericRepository 以在控制器中使用 [关闭]
【发布时间】:2021-12-23 20:03:12
【问题描述】:

我最近一直在寻找可以提高我的代码质量的方法,以及我可以使用并且可以使我的代码尽可能地可重用和清洁的架构。

这里是我迄今为止实现的架构:

IBaseRepository.cs:

    public interface IBaseRepository<T>
    {
        IQueryable<T> Get(GlobalParams itemParams);
        Task<T> GetByID(int id);
        Task<T> Insert(T entity);
        Task Delete(int id);
        Task Delete(T entity);
        Task Update(T entity);
        Task<int> Count();
    }

IClientRepository.cs

public interface IClientRepository : IBaseRepository<Client>
{
    Task<int> CountCompanyClients(GlobalParams globalParams);
}

我的 BaseController.cs

    public class BaseController<T> : ControllerBase where T : class
            {
                protected readonly ConcreetDataContext _context;
                protected readonly IBaseRepository<T> _repo;
                protected readonly DbSet<T> _dbSet;
        
                public BaseController(ConcreetDataContext context, IBaseRepository<T> repo)
                {
                    _context = context;
                    _repo = repo;
                    _dbSet = _context.Set<T>();
                }
                
                // Other Methodds...
             }

ClientController.cs

[Route("api/[controller]")]
    [ApiController]
    public class ClientController : BaseController<Client>
    {
        private readonly IClientRepository _clientRepo;
        public ClientController(ConcreetDataContext context, IBaseRepository<Client> repo) : base(context, repo)
        {
            
        }

        [HttpGet("countCompanyClients")]
        public async Task<ActionResult<int>> CountCompanyClients([FromQuery] ClientParams clientParams)
        {
            
        }
    }

如您所见,我想使用 IClientRepository 中的自定义方法:CountCompanyClients。

  1. 我想知道使用存储库中的方法的最佳方式是什么,以及如何注册存储库。

  2. 使用服务从存储库中迁移业务逻辑是否重要?为什么它如此重要?

  3. 我也想借此机会问一下为什么我们注入接口而不是类。

如果您对此架构有任何意见和建议,我真的很想知道。

【问题讨论】:

  • 为什么要同时注入 DbContext 和存储库?这是没有意义的。然而,这既过于宽泛,也过于自以为是。
  • @CamiloTerevinto 实际上你是对的,我不应该在我的控制器中注入上下文,我现在只是在重构我的代码,所以我会在它使用后将其删除毫无意义。感谢您指出这一点!

标签: c# .net-core dependency-injection architecture


【解决方案1】:

CountCompanyClients() 不是存储库模式的一部分。正如您的IBaseRepository 界面所暗示的那样,这种模式就像是对某些对象的基本集合。

CountCompanyClients 中的内容实际上是一个查询,所以我认为你应该有一个单独的架构来实现它。它可以像你喜欢的那样复杂或简单。

public interface IQuery<TArgs, TResult>
{
    public TResult Execute(TArgs args);
}

public class CountCompanyClientsQuery : IQuery<CountCompanyClientsArgs, int>
{
    private DataContext _db;
    
    public CountCompanyClients(DataContext db)
    {
        _db = db;
    }
    
    public int Execute(CountCompanyClientsArgs args)
    {
        return _db.CompanyClients.Count(x => x.CompanyId == args.CompanyId);
    }
}

【讨论】:

  • 这不会让代码变得更复杂吗?我所做的是在我的 ClientController 中注入 IClientRepository 接口作为新属性,因为如果我的 ClientRepository 中有很多其他自定义方法怎么办?
  • 您可能认为它使您的整体代码更加复杂,但它只是引入了一种新模式,同时您的代码都受益于 SRP 等清洁代码原则。
  • 非常感谢@Neil,我想这是最好的方法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-10
  • 1970-01-01
  • 1970-01-01
  • 2017-09-26
  • 2018-02-22
  • 1970-01-01
  • 2012-01-10
相关资源
最近更新 更多