asp.net core中服务的生命周期选项区别与用法详解 -k8凯发
前言最近在做一个小的demo中,在一个界面上两次调用视图组件,并且在视图组件中都调用了数据库查询,结果发现,一直报错,将两个视图组件的调用分离,单独进行,却又是正常的,寻找一番,发现是配置依赖注入服务时,对于服务的生命周期没有配置得当导致,特此做一次实验来认识三者之间(甚至是四者之间的用法及区别)。
本文demo地址(具体见webapi控制器中):https://gitee。com/530521314/koinstance。git (本地下载)一、服务的生命周期在asp。net core中,内置容器负责管理服务的生命周期,从被依赖注入容器创建开始,等我们调用完服务时,到容器释放该服务的所有实力为止,有几种形式表现:1、transient:每次请求服务时,都会创建一个新实例,这种生命周期适合用于轻量级服务(如repository和applicationservice服务)。
2、scoped:为每个http请求创建一个实例,生命周期将横贯整次请求。3、singleton:在第一次请求服务时,为该服务创建一个实例,之后每次请求将会使用第一次创建好的服务。4、instance:与singleton类似,但在应用程序启动时会将该实例注册到容器中,可以理解为比singleton还早存在。
应用程序中相关服务的控制生命周期的方法时通过相应的add*指定,如下三种,当然还可以通过扩展方法来简化configurationservices方法中所见的代码数量。services。addtransient
addscoped
newguid(); } public operation(guid guid) { _guid = guid == guid。empty ? guid。newguid() : guid; } public guid getguid() { return _guid; } } ///
newguid(); } public operationtransient(guid guid) { _guid = guid == guid。empty ? guid。newguid() : guid; } public guid getguid() { return _guid; } } ///
newguid(); } public operationscoped(guid guid) { _guid = guid == guid。empty ? guid。newguid() : guid; } public guid getguid() { return _guid; } } ///
newguid(); } public operationsingleton(guid guid) { _guid = guid == guid。empty ? guid。newguid() : guid; } public guid getguid() { return _guid; } } ///
newguid(); } public operationinstance(guid guid) { _guid = guid == guid。empty ? guid。newguid() : guid; } public guid getguid() { return _guid; } }基础服务具体实现对基础服务的聚合接口,提供统一服务接口public interface ioperationservice { ///
getguid(), $”scoped:” _scopedoperation。getguid(), $”singleton:” _singletonoperation。getguid(), $”instance:” _instanceoperation。
getguid(), }; } }聚合服务的实现在控制器中进行服务注入[route(“api/[controller]”)] [apicontroller] public class valuescontroller : controllerbase { private readonly ioperationservice _operationservice; public valuescontroller(ioperationservice operationservice) { _operationservice = operationservice; } [httpget] [route(nameof(getguidstring))] public actionresult
join(“\n”, _operationservice。getguidstring()); } }在startup中完成服务注入逻辑,这里实现服务注入的方式多种均可。services。addtransient
addscoped
addsingleton
第一次启动程序(不关闭)发起访问:第二次(第一次基础上再次访问)发起访问:可以看见,两次访问下,singleton和instance是相同的,都是由应用程序启动时和应用服务加载时决定完毕,singleton在首次进入服务时进行分配,并始终保持不变,而instance在应用程序启动时,便将实例注入,进入服务也保持着最先的实例,没有重新分配实例。
而transient和scoped则进行着变化。关闭程序,重启,第三次发起访问:可以见到,singleton和instance都发生了变化,也说明了之前在singleton和instance处写上的作用。接下来开始设计transient和scoped的不同之处,对于已有代码加上新功能,此次我们只针对scoped和transient进行比较。
首先在startup中将httpcontextaccessor服务注入,目的是在后期能够针对scoped获取新的服务实例(尽管两个实例是相同的)。services。addhttpcontextaccessor();接着在聚合服务中增加一个方法,用来针对transient、scoped测试。
///
public list
instance。getservice(typeof(ioperationtransient)); var temptransientservice = (ioperationtransient)_httpcontextaccessor。httpcontext。
requestservices。getservice(typeof(ioperationtransient)); var tempscopedservice = (ioperationscoped)_httpcontextaccessor。httpcontext。
requestservices。getservice(typeof(ioperationscoped)); return new list
getguid(), $”手动transient请求服务:” temptransientservice。getguid(), $”原生scoped请求服务:” _scopedoperation。getguid(), $”手动scoped请求服务:” tempscopedservice。
getguid(), }; }在控制器部分调用该聚合服务即可,并返回相应的结果,本次我返回的结果:可以看到,对于scoped来讲,一次请求内多次访问同一个服务是共用一个服务实例的,而对于transient则是,每次访问都是新的服务实例。至此,对于这四种服务生命周期算是掌握的差不多了。
参考:蒋老师文章: https://www。gxlcms。com/article/150103。htm田园里的蟋蟀:https://www。gxlcms。com/article/150102。htm。
1.文章《asp.net core中服务的生命周期选项区别与用法详解》援引自互联网,为网友投稿收集整理,仅供学习和研究使用,内容仅代表作者本人观点,与本网站无关,侵删请点击页脚凯发k8国际手机app下载的联系方式。
2.文章《asp.net core中服务的生命周期选项区别与用法详解》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。