扩展 GenericRepository 以在控制器中使用
Extending GenericRepository to be used in a Controller
我最近一直在寻找可以提高我的代码质量的方法,以及我可以使用的架构,它可以使我的代码尽可能地可重用和干净。
此时这里是我到目前为止实现的架构:
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。
我想知道使用我存储库中的方法的最佳方式是什么,以及如何注册存储库。
使用服务从存储库中移动业务逻辑重要吗?为什么它如此重要?
我也想借此机会问问为什么我们注入接口而不是class。
如果您对此架构有任何评论和一些建议,我真的很想知道。
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);
}
}
我最近一直在寻找可以提高我的代码质量的方法,以及我可以使用的架构,它可以使我的代码尽可能地可重用和干净。
此时这里是我到目前为止实现的架构:
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。
我想知道使用我存储库中的方法的最佳方式是什么,以及如何注册存储库。
使用服务从存储库中移动业务逻辑重要吗?为什么它如此重要?
我也想借此机会问问为什么我们注入接口而不是class。
如果您对此架构有任何评论和一些建议,我真的很想知道。
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);
}
}