MVC应用中服务层依赖注入实现合理性及替代方案咨询
当前实现合理性评估
你的现有写法功能上可以正常运行,结合你明确不需要接口、无单元测试需求的前提,不引入服务接口的选择是符合你的项目实际场景的,不需要为了遵循所谓的「最佳实践」强行增加冗余的接口层。
但现有实现存在可优化的空间:
- 控制器和
AdminServices的实例化逻辑强绑定,后续如果AdminServices需要新增依赖项(比如日志组件、缓存组件),你不仅需要修改AdminServices的构造函数,还需要同步修改所有用到AdminServices的控制器的构造函数,维护成本更高 AdminServices没有交给DI容器管理,无法复用DI容器的生命周期管理能力,没办法全局统一控制AdminServices的实例是跟随请求销毁、还是全局单例,所有实例化逻辑散落在各个控制器中,后续调整成本高
适配你需求的最优替代方案
不需要改动AdminServices的现有实现,也不需要新增接口,只需要做两处调整即可:
- 在项目的DI注册入口(.NET 6+是
Program.cs,.NET 5及更早是Startup.cs的ConfigureServices方法)中直接注册AdminServices的实现类:
// 用Scoped生命周期和请求保持一致,适合大多数业务服务场景 builder.Services.AddScoped<AdminServices>();
- 调整控制器的构造逻辑,直接注入
AdminServices即可,不需要手动实例化:
public class Admin: Controller { private readonly AdminServices _adminServices; public Admin(AdminServices adminServices) { _adminServices = adminServices; } }
这个方案的优势:
- 后续如果
AdminServices需要新增依赖,你只需要修改AdminServices的构造函数、把新增的依赖注册到DI容器即可,所有用到AdminServices的控制器都不需要调整,维护成本大幅降低 - 可以全局统一调整
AdminServices的生命周期,需要单例就改AddSingleton,需要每次调用都新建实例就改AddTransient,不需要修改业务代码
可选扩展方案
如果后续你的项目需求变化,需要引入单元测试或者多实现切换,再补充对应的IAdminServices接口即可,不用提前增加冗余的维护工作。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

