一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

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

服務器之家 - 編程語言 - ASP.NET教程 - Asp.Net Core中服務的生命周期選項區別與用法詳解

Asp.Net Core中服務的生命周期選項區別與用法詳解

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

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

前言

最近在做一個小的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方法中所見的代碼數量。

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

二、代碼設計服務生命周期

首先設計一些服務相關的操作接口

?
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
 {
 
 }
 
基礎服務接口

其次對這些操作類予以實現并生成相關服務

?
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>
 /// 常規服務
 /// </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>
 /// 瞬時服務
 /// </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>
 /// 單次請求內服務固定
 /// </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>
 /// 所有請求內固定服務
 /// </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>
 /// 應用程序內固定服務
 /// </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;
 }
 }
 
基礎服務具體實現

對基礎服務的聚合接口,提供統一服務接口

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

對基礎服務的聚合實現,將基礎服務全部接入進來作為統一服務

?
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>
 /// 服務調用
 /// </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(),
 };
 }
 }
 
聚合服務的實現

在控制器中進行服務注入

?
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中完成服務注入邏輯,這里實現服務注入的方式多種均可。

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

通過訪問預期Api地址可以得到不同的四種基礎服務的Guid信息,

第一次啟動程序(不關閉)發起訪問:

Asp.Net Core中服務的生命周期選項區別與用法詳解  

第二次(第一次基礎上再次訪問)發起訪問:

Asp.Net Core中服務的生命周期選項區別與用法詳解  

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

關閉程序,重啟,第三次發起訪問:

Asp.Net Core中服務的生命周期選項區別與用法詳解  

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

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

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

?
1
services.AddHttpContextAccessor();

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

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

在聚合服務實現中實現該方法并對已有的服務重新獲取實例,得到不同實例下的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請求服務:"+_transientOperation.GetGuid(),
 $"手動Transient請求服務:"+ tempTransientService.GetGuid(),
 $"原生Scoped請求服務:"+_scopedOperation.GetGuid(),
 $"手動Scoped請求服務:"+tempScopedService.GetGuid(),
 };
 }

在控制器部分調用該聚合服務即可,并返回相應的結果,本次我返回的結果:

Asp.Net Core中服務的生命周期選項區別與用法詳解  

可以看到,對于Scoped來講,一次請求內多次訪問同一個服務是共用一個服務實例的,而對于Transient則是,每次訪問都是新的服務實例。

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

總結

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

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久久精品无码人妻无码AV蜜臀 | 国模一区二区三区视频一 | chinesemature老女人 | 深夜日韩 | 成人蜜桃网 | 日日操日日舔 | 丝瓜视频成人在线观看 | 糖心vlog麻豆精东影业传媒 | 国产精品国产三级国产专区不 | 日本花季传媒2020旧版安卓 | 人皮高跟鞋在线观看 | 成年性香蕉漫画在线观看 | 亚洲高清在线视频 | 亚洲一区 在线播放 | 国产欧美日韩免费一区二区 | 青草草在线 | 97精品国产高清在线看入口 | 国产美女屁股直流白浆视频无遮挡 | 国产午夜亚洲精品理论片不卡 | 我与旗袍老师疯狂床震 | caoporn人人 | 34看网片午夜理 | 日本一级不卡一二三区免费 | 青青国产精品 | 肉色欧美久久久久久久蜜桃 | aⅴ导航站| 91日本在线观看亚洲精品 | 美女在尿口隐私视频 | 99久久国产综合精品女小说 | 第一次做m被调教经历 | 色综合色狠狠天天综合色 | 范冰冰特黄xx大片 | 接吻吃胸摸下面啪啪教程 | 日本免费全黄一级裸片视频 | 香港三级系列在线播放 | 嗯啊好大视频 | 无码一区国产欧美在线资源 | 高清国产精品久久 | 男同gay玩奴男同玩奴 | 香蕉久久综合 | 美女全身无遮挡 |