手机版

服务生命周期选项在Asp.Net核心区的区别和使用

时间:2021-08-29 来源:互联网 编辑:宝哥软件园 浏览:

前言

最近,在一个小演示中,视图组件在一个接口上被调用了两次,数据库查询在视图组件中被调用。结果发现一直都有报错,两个视图组件的调用是分开进行的,但都是正常的。搜索后发现,在配置依赖注入服务时,服务的生命周期配置不正确。因此,进行了一项实验来了解三者(甚至是四者之间的用法和区别)。

本文中演示的地址是:https://gitee.com/530521314/koinstance.git(本地下载)

一、使用寿命周期

在Asp.Net核心中,内置容器负责管理服务的生命周期,从创建依赖注入容器到我们调用服务,直到容器释放服务的全部力量,这表现为几种形式:

1.瞬态:每次请求服务时,都会创建一个新的实例。这个生命周期适用于轻量级服务(如Repository和ApplicationService)。

2.作用域:为每个HTTP请求创建一个实例,生命周期将遍历整个请求。

3.SingleTon:当第一次请求服务时,为服务创建一个实例,然后为每个请求使用第一次创建的服务。

4.实例:与SingleTon类似,但是在应用程序启动时会在容器中注册,可以理解为SingleTon之前就存在了。

控制应用程序中相关服务生命周期的方法由相应的Add*指定,如下所示。当然,在ConfigurationServices方法中看到的代码数量可以通过扩展方法来简化。

服务。AddTransientIApplicationService,ApplicationService();服务。AddScopedIApplicationService,ApplicationService();服务。AddSingletonIApplicationService,ApplicationService();二、代码设计的服务生命周期

首先,设计了一些与服务相关的操作界面

公共接口I operation { Guid GetGuid();}公共接口iooperationsingleton : I operation { }公共接口iooperationscoped : I operation { }公共接口iooperationsingleton : I operation { }公共接口iooperationinstance : I operation { }基本服务接口实现这些操作类并生成相关服务

///summary////general service////summary public class operation : I operation { private readonly guid _ guid;public Operation() { _guid=Guid。NewGuid();}公共操作(Guid guid) { _guid=guid==Guid。空的?Guid。NewGuid(): guid;} public Guid GetGuid(){ return _ Guid;} }///summary////transient service////summary public class operation transient : iooperationtransient { private readonly guid _ guid;public operation transient(){ _ Guid=Guid。NewGuid();} public operation transient(Guid Guid){ _ Guid=Guid==Guid。空的?Guid。NewGuid(): guid;} public Guid GetGuid(){ return _ Guid;} }///summary////单个请求内的固定服务////summary公共类操作作用域为: ioperationscoped { private readonly guid _ guid;public OperationScoped(){ _ Guid=Guid。NewGuid();}公共操作作用域(Guid guid) { _guid=guid==Guid。空的?Guid。NewGuid(): guid;} public Guid GetGuid(){ return _ Guid;} }///Summary////所有请求内的固定服务////Summary公共类操作Singleton : iooperationsingleton { Private Readonly guid _ guid;public operation singleton(){ _ Guid=Guid。NewGuid();} public operation singleton(Guid Guid){ _ Guid=Guid==Guid。空的?Guid。NewGuid(): guid;} public Guid GetGuid(){ return _ Guid;} }///summary////应用程序内的固定服务////summary公共类操作实例: iooperationinstance { private readonly guid _ guid;public operation instance(){ _ Guid=Guid。NewGuid();} public operation instance(Guid Guid){ _ Guid=Guid==Guid。空的?Guid。NewGuid(): guid;} public Guid GetGuid(){ return _ Guid;}}基础服务实现基础服务的聚合接口,提供统一的服务接口

公共接口iooperationservice {///summary///获取四种形式的全局唯一标识符码////summary////returns/returns Liststring GetGuidString();}聚合服务接口对基础服务的聚合实现,将基础服务全部接入进来作为统一服务

///摘要///服务调用////摘要公共类operations service : iooperationservice { public iooperationontranstuent _ transientooperation { get;} public iooperationscoped _ scope操作{ get} public iooperationsingleton _ singleton操作{ get} public iooperationinstance _ instance操作{ get}公共操作服务(iooperationontracient transient操作,iooperationscoped scope操作,iooperationsingleton操作,iooperationinstance实例操作){ _ transient operation=transient operation;_作用域操作=作用域操作;_单线操作=单线操作;_实例操作=实例操作;} public Liststring GetGuidString(){ 0返回新的list string(){ $ ' transient : ' _瞬态操作.GetGuid(),$ ' Scoped: ' _ scopedOperation .GetGuid(),$ ' singleton : ' _ singleton操作.GetGuid(),$ ' instance : ' _ instance operation .GetGuid(),};} }聚合服务的实现在控制器中进行服务注入

[路由(' API/[控制器]')][API控制器]公共类值控制器:控制器基础{ private readonly iooperationservice _ operation service;公共值控制器(iooperationservice operation service){ _ operation service=operation service;}[HttpGet][Route(GetGuidString的名称))]public actionresultString GetGuidString(){ return string .加入(' \n ',_operationService .GetGuidString());} }在启动中完成服务注入逻辑,这里实现服务注入的方式多种均可。

服务addtransientinoperationtransient,operation transient();服务AddScopedIOperationScoped,OperationScoped();服务addsingletionoperationsingleton,OperationSingleton();//应用程序启动时便注入该实例服务。添加单实例操作实例(新的操作实例(Guid .空的));服务addtransientationoperationservice,OperationService();通过访问预期美国石油学会(美国石油协会)地址可以得到不同的四种基础服务的全局唯一标识符信息,

第一次启动程序(不关闭)发起访问:

第二次(第一次基础上再次访问)发起访问:

可以看见,两次访问下单身和情况是相同的,都是由应用程序启动时和应用服务加载时决定完毕单身在首次进入服务时进行分配,并始终保持不变,而情况在应用程序启动时,便将实例注入,进入服务也保持着最先的实例,没有重新分配实例。而短暂的和审视则进行着变化。

关闭程序,重启,第三次发起访问:

可以见到单身和情况都发生了变化,也说明了之前在一个和情况处写上的作用。

接下来开始设计短暂的和审视的不同之处,对于已有代码加上新功能,此次我们只针对审视和短暂的进行比较。

首先在启动中将HttpContextAccessor服务注入,目的是在后期能够针对审视获取新的服务实例(尽管两个实例是相同的)。

服务AddHttpContextAccessor();接着在聚合服务中增加一个方法,用来针对短暂的、有限的测试。

///摘要///获取短暂的、有限的的全局唯一标识符码////summary////returns/returns Liststring GetTransientAndScopedGuidString();在聚合服务实现中实现该方法并对已有的服务重新获取实例,得到不同实例下的全局唯一标识符码。

public Liststring GetTransientAndScopedGuidString(){//var tempTransientService=(iooperationtransclient)service locator。实例。GetService(类型为(iOperationTransient));var tempTransientService=(iooperationontranstuent)_ HttpContextaccessor。HttpContext . RequestSerVices . GetServiCe(type of(iooperationontranslent));var tempScopedService=(iooperationscoped)_ httpContextAccessor。HttpContext . RequestSerVices . GetServiCe(type of(iOperationScoped));返回新的Liststring() {$ '本机瞬态请求服务:' _瞬态操作。getguid(),$ '手动瞬态请求服务:' temptransientservice。getguid(),$ '本机作用域请求服务:' _作用域操作。getguid(),$“手动范围请求服务:”TempScopedService。getguid(),};}只需调用控制器部分的聚合服务,返回相应的结果。这次我返回的结果是:

可以看到,对于Scoped,在一个请求中对同一服务的多次访问共享一个服务实例,而对于Transient,每次访问都是一个新的服务实例。

至此,这四种服务的生命周期基本掌握。

参考:

蒋老师的文章:

花园里的蟋蟀:https://www.jb51.net/article/150102.htm

摘要

以上就是本文的全部内容。希望本文的内容对大家的学习或工作有一定的参考价值。有问题可以留言交流。谢谢你的支持。

版权声明:服务生命周期选项在Asp.Net核心区的区别和使用是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。