当前位置:开发工具->.NET ->谈谈dotnet core默认DI框架的Scope生命周期的理解及常见问题

原创版权标志谈谈dotnet core默认DI框架的Scope生命周期的理解及常见问题

作者:阿郎  发表时间:2018/8/18 21:33:19  阅读:
[摘要] Unhandled Exception: System.InvalidOperationException: Cannot consume scoped service ’xxxDbContext’ from singleton ’Microsoft.Extensions.Hosting.IHostedService’
使用支付宝扫码领红包,余额宝付款才可以使用红包哦!不要忘记哈。每天扫一次,天天赚红包!!可以将二维码保存到手机,每天直接扫码领红包啦!!
其实在刚刚接触dotnet core的时候,DI框架的三种生命周期除却单例和瞬时周期外,Scope周期我一直没有理解,到现在其实也是一知半解。Scope的意思是范围,作用域。我们可以直观的理解为在一个特定的范围或是作用域内生效。后来我在项目开发的时候就遇到了Scope生命周期的一个问题。具体请参考: <<asp.net core 依赖注入实现全过程粗略剖析(3)>>
首先借鉴一个例子上一段代码,这是参考了 Dependency Injection - Service Lifetimes
例子完全是照搬下来的。你自己可以实践一遍。
而我遇到的问题就是因为在遇到错误的时候,想到了是因为生命周期的问题,但是由于不理解不清楚具体的细节导致不能迅速解决。EF core在dotnet core中的默认生命周期是Scope,每一次的HTTP请求或者更完整的说是一次会话过程都是共用一个DbContext,即一个EF Core上下文。而我之前那个项目的需求是定时的去更新一个任务数据信息,其中需要查询数据库信息,随后去更新数据库。我一开始下意识的就把在ConfigureService中注入的数据库上下文给拿了进来,在定时类的构造函数中注入了。最后就报错了:
Unhandled Exception: System.InvalidOperationException: Cannot consume scoped service 'xxxDbContext' from singleton 'Microsoft.Extensions.Hosting.IHostedService'
我一分析这个报错,就觉得应该是生命周期问题,但是当时并没有联系到DbContext的生命周期,因为当时只是知道用DI但是不了解具体细节。也没有留心到报错中的scoped service...  后来就查了资料,于是做了个分析:
在dotnet core中的的每次浏览器会话都是共用一个不同的DbContext,只有在同一会话中才是共用一个DbContext。而我这里的定时请求是另外的一个会话,他不能引入在StartUp类中注入的上下文依赖:AddDbContext... 因为这个定时任务并没有去调用StartUp类中的ConfigureService方法中注入的依赖,所以定时任务中的DbContext的依赖注入就会报错。那么我们可以在定时任务中再去获取指定接口/抽象类的服务,这里是DbContext类。于是我们可以这样:
var context = _scope.ServiceProvider.GetService<xxxxDbContext>();
如此依赖便获取到了指定的上下文服务。
其实对于CreateScope方法,顾名思义,是重新创建一个Scope生命周期的服务提供者(ServiceProvider)。
    
微信扫码关注公众号CPP技术网,微信号cpp_coder,关注我们的公众号,阅读更多精彩内容!每天还可以领取大红包哦!!!每天还可以领取大红包哦!!!每天还可以领取大红包哦!!!
文章来源:C++技术网原创文章版权为网站和作者共同所有,会员文章禁止转载。非会员文章转载做好本文超链接即表示授权转载。通过文章下面的分享按钮可以自由分享所有文章。

返回顶部

在线提问
问题标题:
问题描述:(简陋的描述会导致问题被最后回答、没有针对性回答甚至无法解答。请确保问题描述的足够清楚。)