ASP.NET Core MVC业务与Model层如何实现SOLID原则?控制器注入最佳实践
ASP.NET Core MVC分层依赖方案最佳实践解答
结论
你当前使用的Controller仅注入BLL接口、BLL内部依赖Repository接口完成数据操作的方案是符合分层架构规范的最优实现,不建议在Controller中同时注入BLL和Repository、由Controller读取数据后传给BLL处理。
核心原因
- 符合分层架构的职责边界要求
经典三层架构中,表现层(Controller)、业务逻辑层(BLL)、数据访问层(Repository)的核心规则是每层仅与紧邻的下层交互,上层无需感知下层的实现细节。Controller的核心职责仅为请求参数校验、响应结果封装,所有业务规则、数据操作的编排都应该收敛到BLL层。如果让Controller直接调用Repository,相当于把本该BLL负责的业务逻辑上下游拆分到了表现层,后续修改业务逻辑时需要同时调整Controller和BLL代码,维护成本会大幅提升。 - 保证代码复用性
同一份业务逻辑往往会被多个Controller调用,如果把Repository查询逻辑写在Controller中,会出现大量重复的查询代码,且逻辑分散后很容易出现不同Controller查询同一份数据的规则不一致的问题。将数据查询和业务处理逻辑统一封装在BLL的同一个方法中,所有调用方只需调用该BLL方法即可,逻辑统一,修改时仅需调整一处。 - 保障事务一致性
大部分业务操作需要多个数据读写动作在同一个事务中完成,如果数据查询逻辑放在Controller、业务写入逻辑放在BLL,你需要将事务边界定义在Controller层,或是将事务对象从Controller传入BLL,完全违背了事务由业务层管控的原则,极易出现事务泄漏、数据不一致的问题。 - 降低单元测试成本
当前的分层依赖方案中,单元测试Controller时只需Mock BLL接口,测试BLL时只需Mock Repository接口,每层的测试都无需关心其他层的实现。如果Controller同时依赖BLL和Repository,单元测试时需要同时Mock两个依赖,测试用例的复杂度会显著提升。
特殊场景例外
如果存在完全不需要业务加工的纯数据查询场景,比如直接查询枚举字典表返回给前端,无任何逻辑处理,可以直接在Controller中注入Repository完成查询,但是这类场景需要团队统一约定使用范围,不要随意和常规业务逻辑的调用方式混用。
内容的提问来源于stack exchange,提问作者Faisal
相关产品推荐
相关产品推荐

