国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - ASP.NET教程 - Asp.Net Core中服務(wù)的生命周期選項(xiàng)區(qū)別與用法詳解

Asp.Net Core中服務(wù)的生命周期選項(xiàng)區(qū)別與用法詳解

2020-06-03 14:58微笑刺客D ASP.NET教程

這篇文章主要給大家介紹了關(guān)于Asp.Net Core中服務(wù)的生命周期選項(xiàng)區(qū)別與用法的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

最近在做一個(gè)小的Demo中,在一個(gè)界面上兩次調(diào)用視圖組件,并且在視圖組件中都調(diào)用了數(shù)據(jù)庫查詢,結(jié)果發(fā)現(xiàn),一直報(bào)錯(cuò),將兩個(gè)視圖組件的調(diào)用分離,單獨(dú)進(jìn)行,卻又是正常的,尋找一番,發(fā)現(xiàn)是配置依賴注入服務(wù)時(shí),對于服務(wù)的生命周期沒有配置得當(dāng)導(dǎo)致,特此做一次實(shí)驗(yàn)來認(rèn)識(shí)三者之間(甚至是四者之間的用法及區(qū)別)。

本文demo地址(具體見WebApi控制器中):https://gitee.com/530521314/koInstance.git 

 一、服務(wù)的生命周期

在Asp.Net Core中,內(nèi)置容器負(fù)責(zé)管理服務(wù)的生命周期,從被依賴注入容器創(chuàng)建開始,等我們調(diào)用完服務(wù)時(shí),到容器釋放該服務(wù)的所有實(shí)力為止,有幾種形式表現(xiàn):

  1、Transient:每次請求服務(wù)時(shí),都會(huì)創(chuàng)建一個(gè)新實(shí)例,這種生命周期適合用于輕量級(jí)服務(wù)(如Repository和ApplicationService服務(wù))。

  2、Scoped:為每個(gè)HTTP請求創(chuàng)建一個(gè)實(shí)例,生命周期將橫貫整次請求。

  3、SingleTon:在第一次請求服務(wù)時(shí),為該服務(wù)創(chuàng)建一個(gè)實(shí)例,之后每次請求將會(huì)使用第一次創(chuàng)建好的服務(wù)。

  4、Instance:與SingleTon類似,但在應(yīng)用程序啟動(dòng)時(shí)會(huì)將該實(shí)例注冊到容器中,可以理解為比SingleTon還早存在。

應(yīng)用程序中相關(guān)服務(wù)的控制生命周期的方法時(shí)通過相應(yīng)的Add*指定,如下三種,當(dāng)然還可以通過擴(kuò)展方法來簡化ConfigurationServices方法中所見的代碼數(shù)量。

?
1
2
3
services.AddTransient<IApplicationService, ApplicationService>();
services.AddScoped<IApplicationService, ApplicationService>();
services.AddSingleton<IApplicationService, ApplicationService>();

二、代碼設(shè)計(jì)服務(wù)生命周期

首先設(shè)計(jì)一些服務(wù)相關(guān)的操作接口

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public interface IOperation
 {
 Guid GetGuid();
 }
 
 public interface IOperationTransient: IOperation
 {
 
 }
 
 public interface IOperationScoped : IOperation
 {
 
 }
 
 public interface IOperationSingleton : IOperation
 {
 
 }
 
 public interface IOperationInstance : IOperation
 {
 
 }
 
基礎(chǔ)服務(wù)接口

其次對這些操作類予以實(shí)現(xiàn)并生成相關(guān)服務(wù)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/// <summary>
 /// 常規(guī)服務(wù)
 /// </summary>
 public class Operation : IOperation
 {
 private readonly Guid _guid;
 
 public Operation()
 {
 _guid = Guid.NewGuid();
 }
 
 public Operation(Guid guid)
 {
 _guid = guid == Guid.Empty ? Guid.NewGuid() : guid;
 }
 
 public Guid GetGuid()
 {
 return _guid;
 }
 }
 
 /// <summary>
 /// 瞬時(shí)服務(wù)
 /// </summary>
 public class OperationTransient : IOperationTransient
 {
 private readonly Guid _guid;
 
 public OperationTransient()
 {
 _guid = Guid.NewGuid();
 }
 
 public OperationTransient(Guid guid)
 {
 _guid = guid == Guid.Empty ? Guid.NewGuid() : guid;
 }
 
 public Guid GetGuid()
 {
 return _guid;
 }
 }
 
 /// <summary>
 /// 單次請求內(nèi)服務(wù)固定
 /// </summary>
 public class OperationScoped : IOperationScoped
 {
 private readonly Guid _guid;
 
 public OperationScoped()
 {
 _guid = Guid.NewGuid();
 }
 
 public OperationScoped(Guid guid)
 {
 _guid = guid == Guid.Empty ? Guid.NewGuid() : guid;
 }
 
 public Guid GetGuid()
 {
 return _guid;
 }
 }
 
 
 /// <summary>
 /// 所有請求內(nèi)固定服務(wù)
 /// </summary>
 public class OperationSingleton : IOperationSingleton
 {
 private readonly Guid _guid;
 
 public OperationSingleton()
 {
 _guid = Guid.NewGuid();
 }
 
 public OperationSingleton(Guid guid)
 {
 _guid = guid == Guid.Empty ? Guid.NewGuid() : guid;
 }
 
 public Guid GetGuid()
 {
 return _guid;
 }
 }
 
 /// <summary>
 /// 應(yīng)用程序內(nèi)固定服務(wù)
 /// </summary>
 public class OperationInstance : IOperationInstance
 {
 private readonly Guid _guid;
 
 public OperationInstance()
 {
 _guid = Guid.NewGuid();
 }
 
 public OperationInstance(Guid guid)
 {
 _guid = guid == Guid.Empty ? Guid.NewGuid() : guid;
 }
 
 public Guid GetGuid()
 {
 return _guid;
 }
 }
 
基礎(chǔ)服務(wù)具體實(shí)現(xiàn)

對基礎(chǔ)服務(wù)的聚合接口,提供統(tǒng)一服務(wù)接口

?
1
2
3
4
5
6
7
8
9
10
public interface IOperationService
 {
 /// <summary>
 /// 獲取四種形式的Guid碼
 /// </summary>
 /// <returns></returns>
 List<string> GetGuidString();
 }
 
聚合服務(wù)接口

對基礎(chǔ)服務(wù)的聚合實(shí)現(xiàn),將基礎(chǔ)服務(wù)全部接入進(jìn)來作為統(tǒng)一服務(wù)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/// <summary>
 /// 服務(wù)調(diào)用
 /// </summary>
 public class OperationService : IOperationService
 {
 public IOperationTransient _transientOperation { get; }
 public IOperationScoped _scopedOperation { get; }
 public IOperationSingleton _singletonOperation { get; }
 public IOperationInstance _instanceOperation { get; }
 
 public OperationService(IOperationTransient transientOperation,
 IOperationScoped scopedOperation,
 IOperationSingleton singletonOperation,
 IOperationInstance instanceOperation)
 {
 _transientOperation = transientOperation;
 _scopedOperation = scopedOperation;
 _singletonOperation = singletonOperation;
 _instanceOperation = instanceOperation;
 }
 
 public List<string> GetGuidString()
 {
 return new List<string>()
 {
 $"Transient:"+_transientOperation.GetGuid(),
 $"Scoped:"+_scopedOperation.GetGuid(),
 $"Singleton:" +_singletonOperation.GetGuid(),
 $"Instance:"+_instanceOperation.GetGuid(),
 };
 }
 }
 
聚合服務(wù)的實(shí)現(xiàn)

在控制器中進(jìn)行服務(wù)注入

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[Route("api/[controller]")]
 [ApiController]
 public class ValuesController : ControllerBase
 {
 private readonly IOperationService _operationService;
 
 public ValuesController(IOperationService operationService)
 {
 _operationService = operationService;
 }
 
 [HttpGet]
 [Route(nameof(GetGuidString))]
 public ActionResult<string> GetGuidString()
 {
 return string.Join("\n", _operationService.GetGuidString());
 }
 }

在StartUp中完成服務(wù)注入邏輯,這里實(shí)現(xiàn)服務(wù)注入的方式多種均可。

?
1
2
3
4
5
services.AddTransient<IOperationTransient, OperationTransient>();
services.AddScoped<IOperationScoped, OperationScoped>();
services.AddSingleton<IOperationSingleton, OperationSingleton>();//應(yīng)用程序啟動(dòng)時(shí)便注入該實(shí)例
services.AddSingleton<IOperationInstance>(new OperationInstance(Guid.Empty));
services.AddTransient<IOperationService, OperationService>();

通過訪問預(yù)期Api地址可以得到不同的四種基礎(chǔ)服務(wù)的Guid信息,

第一次啟動(dòng)程序(不關(guān)閉)發(fā)起訪問:

Asp.Net Core中服務(wù)的生命周期選項(xiàng)區(qū)別與用法詳解  

第二次(第一次基礎(chǔ)上再次訪問)發(fā)起訪問:

Asp.Net Core中服務(wù)的生命周期選項(xiàng)區(qū)別與用法詳解  

可以看見,兩次訪問下,Singleton和Instance是相同的,都是由應(yīng)用程序啟動(dòng)時(shí)和應(yīng)用服務(wù)加載時(shí)決定完畢,Singleton在首次進(jìn)入服務(wù)時(shí)進(jìn)行分配,并始終保持不變,而Instance在應(yīng)用程序啟動(dòng)時(shí),便將實(shí)例注入,進(jìn)入服務(wù)也保持著最先的實(shí)例,沒有重新分配實(shí)例。而Transient和Scoped則進(jìn)行著變化。

關(guān)閉程序,重啟,第三次發(fā)起訪問:

Asp.Net Core中服務(wù)的生命周期選項(xiàng)區(qū)別與用法詳解  

可以見到,Singleton和Instance都發(fā)生了變化,也說明了之前在Singleton和Instance處寫上的作用。

接下來開始設(shè)計(jì)Transient和Scoped的不同之處,對于已有代碼加上新功能,此次我們只針對Scoped和Transient進(jìn)行比較。

首先在StartUp中將HttpContextAccessor服務(wù)注入,目的是在后期能夠針對Scoped獲取新的服務(wù)實(shí)例(盡管兩個(gè)實(shí)例是相同的)。

?
1
services.AddHttpContextAccessor();

接著在聚合服務(wù)中增加一個(gè)方法,用來針對Transient、Scoped測試。

?
1
2
3
4
5
/// <summary>
/// 獲取Transient、Scoped的Guid碼
/// </summary>
/// <returns></returns>
List<string> GetTransientAndScopedGuidString();

在聚合服務(wù)實(shí)現(xiàn)中實(shí)現(xiàn)該方法并對已有的服務(wù)重新獲取實(shí)例,得到不同實(shí)例下的Guid碼。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public List<string> GetTransientAndScopedGuidString()
 {
 //var tempTransientService = (IOperationTransient)ServiceLocator.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<string>()
 {
 $"原生Transient請求服務(wù):"+_transientOperation.GetGuid(),
 $"手動(dòng)Transient請求服務(wù):"+ tempTransientService.GetGuid(),
 $"原生Scoped請求服務(wù):"+_scopedOperation.GetGuid(),
 $"手動(dòng)Scoped請求服務(wù):"+tempScopedService.GetGuid(),
 };
 }

在控制器部分調(diào)用該聚合服務(wù)即可,并返回相應(yīng)的結(jié)果,本次我返回的結(jié)果:

Asp.Net Core中服務(wù)的生命周期選項(xiàng)區(qū)別與用法詳解  

可以看到,對于Scoped來講,一次請求內(nèi)多次訪問同一個(gè)服務(wù)是共用一個(gè)服務(wù)實(shí)例的,而對于Transient則是,每次訪問都是新的服務(wù)實(shí)例。

至此,對于這四種服務(wù)生命周期算是掌握的差不多了。 

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對服務(wù)器之家的支持。

原文鏈接:https://www.cnblogs.com/CKExp/p/9823076.html

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 最近韩国日本免费观看mv免费版 | 亚洲一区二区三区免费观看 | 97人人爱| 久久久久久av | 国产福利电影 | 欧美电影一区 | 国产免费天天看高清影视在线 | 国产亚洲一区二区三区 | 亚洲视频在线观看免费 | 亚洲国产精品成人 | 亚洲在线电影 | 91视频黄色 | 黄色一级小视频 | 欧美精品一区二区三区在线 | 亚洲a在线观看 | 国产精品3区 | 在线亚洲精品 | 日本精品在线观看 | 精品www| 亚洲一区在线日韩在线深爱 | 午夜影院| 久久中文字幕一区 | 亚洲视频二区 | 91精品久久 | 国产色| 成人免费一区二区三区视频网站 | 男女全黄一级一级高潮免费看 | 81精品国产乱码久久久久久 | av一区二区三区 | 国产成人精品一区二区三区四区 | 九九只有精品 | 午夜桃色 | 欧美成人精品一区二区三区 | 欧美一级二级视频 | 久久奸| 高清一区二区三区视频 | 日韩免费 | 亚洲二区视频 | 夜夜夜操 | 亚洲啊v | 色偷偷噜噜噜亚洲男人 |