.NET 5默认DI下同一控制器多服务共享IUnitOfWork方案咨询
最优解决方案:调整IUnitOfWork的注入生命周期为Scoped
你遇到的问题根源是对DI容器的生命周期理解有误:Transient生命周期的服务是每次被DI解析时都会生成全新实例,而非你之前认为的每次请求分配一个,这才导致同一个请求内注入到多个服务的IUnitOfWork都是独立实例。
ASP.NET Core官方DI容器的Scoped生命周期天然匹配你的需求:同一个HTTP请求对应同一个Scoped作用域,在该作用域内多次解析同一个服务,只会拿到同一个实例。
你只需要修改Startup.cs中的注入配置即可:
// 将原Transient注册改为Scoped services.AddScoped<IUnitOfWork, UnitOfWork>();
修改后不需要改动任何现有服务、控制器的注入逻辑,所有注入到当前请求内服务的IUnitOfWork会自动共享同一个实例,天然支持多服务操作走同一个事务,无需额外手动赋值、基类继承或者工厂实现,是.NET Core/.NET 5+下该场景的官方最佳实践。
其他场景补充说明
如果存在非HTTP请求的场景需要共享UoW(比如后台定时任务、控制台应用),你可以手动创建Scoped作用域来实现同一个业务流程内共享UoW:
// 注入IServiceScopeFactory后手动创建作用域 using var scope = _serviceScopeFactory.CreateScope(); var sp = scope.ServiceProvider; // 同一个作用域内解析的所有服务拿到的IUnitOfWork都是同一个 var mainService = sp.GetRequiredService<MainService>(); var service2 = sp.GetRequiredService<Service2>(); // 执行业务逻辑
旧方案问题说明
- 手动替换UoW的方案:每个服务初始化时都会生成冗余UoW实例,不仅浪费资源,还可能出现事务未提交就被释放、线程安全等隐性问题。
- 工厂懒加载方案:本质是手动实现了Scoped生命周期的逻辑,但完全没有必要,DI容器原生已经提供了成熟实现,自己维护工厂反而容易出现作用域管理不当的内存泄漏问题。
内容的提问来源于stack exchange,提问作者OIDOCROP
相关产品推荐
相关产品推荐

