首页 > 解决方案 > 扩展 GenericRepository 以在控制器中使用

问题描述

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

在这一点上,这是我迄今为止实现的架构:

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

客户端控制器.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. 我也想借此机会问一下为什么我们注入接口而不是类。

如果您对此架构有任何评论和一些建议,我真的很想了解它们。

标签: c#.net-coredependency-injectionarchitecture

解决方案


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

推荐阅读