使用Unity依赖注入时DatabaseContext的正确释放方式
问题1解答:是否需要实现IDisposable手动释放数据库连接?
必须实现IDisposable手动释放,不能完全依赖GC自动回收,原因如下:
- EF的
DbContext封装的数据库连接属于非托管资源,GC回收非托管资源的时机不可控,会导致数据库连接长时间被占用,高并发场景下极易触发数据库连接池耗尽报错 - 你提供的辅助方法逻辑中,异常分支返回的
DatabaseContext没有存入请求上下文,这部分实例如果不手动释放会完全泄漏 - 你已经使用了
HierarchicalLifetimeManager注册服务,Unity会在请求结束、子容器销毁时自动调用所有实现了IDisposable的服务实例的Dispose方法,不需要你手动触发调用
问题2解答:使用标准Dispose模式还是简单实现即可?
分场景判断:
- 如果你的
CompaniesService不会被其他类继承,也不会额外引入其他非托管资源,简单实现完全够用,建议在你现有写法基础上做空值兼容和终结抑制优化:
public void Dispose() { (_db as IDisposable)?.Dispose(); GC.SuppressFinalize(this); }
- 如果后续计划给
CompaniesService做派生扩展、或者会加入其他非托管资源,建议使用完整的标准Dispose模式,避免资源泄漏。
额外注意事项
如果你的DatabaseContext是请求级共享实例,不要在每个服务中单独释放,否则会导致同请求内其他持有该Context的服务调用时报“上下文已释放”错误,这种场景建议改为在请求生命周期结束的统一拦截点(比如ASP.NET的请求结束事件、中间件)释放请求上下文中存储的DatabaseContext即可。
内容的提问来源于stack exchange,提问作者dkotsopo
相关产品推荐
相关产品推荐

