Asp.net core依賴注入服務生存期踩坑記錄
寫在開頭
今天我本想實現元件全域性共享資料(狀態管理),儲存工廠名,使用者登入id,裝置編碼等欄位,以便全域性共享。
但我在a元件設定的值到了b元件就不見了。
遇到的問題,與依賴注入服務生存期有關,我們知道依賴注入服務一共有三種:
AddScoped
:作用域
AddTransient
:瞬時
AddSingleton
:單例
內容
set state,在另一個元件中點選事件列印state
public record AppState
{
public string Factory { get; private set; }
public string UserId { get; private set; }
public string EquipId { get; private set; }
public void SetFactory(string factory)
{
if (string.IsNullOrWhiteSpace(factory))
return;
Factory = factory;
}
public void SetUserId(string userId)
{
if (string.IsNullOrWhiteSpace(userId))
return;
UserId = userId;
}
public void SetEquipId(string equipId)
{
if (string.IsNullOrWhiteSpace(equipId))
return;
EquipId = equipId;
}
}
//program.cs
builder.Services.AddScoped<AppState>();
//Home.razor
@inject AppState appState
appState.SetEquipId(Id);
appState.SetFactory(Factory);
Console.WriteLine("這裡是home:{0}",appState);
//login.razor
@inject AppState appState
@inject UserAuthenticationStateProvider UserAuthenticationStateProvider
var a = await UserAuthenticationStateProvider.GetAuthenticationStateAsync();
appState.SetUserId(a.User.FindFirst("EmployeeNo").Value);
Console.WriteLine("這裡是login:{0}",appState);
navMan.NavigateTo($"/{appState.Factory}/{appState.EquipId}",true);//跳轉回home
可以看到,資料不見了
罪魁禍首則是NavigateTo
方法的true
引數
翻閱微軟文件,以下解釋:
如果為 true,則繞過客戶端路由並強制瀏覽器從伺服器載入新頁面,無論 URI 是否通常由客戶端路由器處理。
強制載入頁面,那麼也就是在這裡點選了重新整理或者直接修改路由進行導航,它的scoped
就改變了
那麼去掉true,讓路由幫我們完成:
發現狀態獲取成功
此時新開一個標籤頁:http://localhost:5000/DP10/888
列印出的結果與之前不同了,可我們在原先第一個標籤頁,也就是http://localhost:5000/DP02/123
,列印出的結果仍是DP02
,由此可知,作用域僅限於當前標籤頁
"對於 Web 應用,指定了作用域的生存期指明瞭每個客戶端請求(連線)建立一次服務。"
接下來我們測試singleton
發現不管在哪裡設定,在哪裡獲取,都是同步的,舉個例子:
a使用者登入系統,設定
userid
為a,b使用者登入系統,設定userid
為b,此時,a使用者的userid
也變成了b"來自依賴關係注入容器的服務實現的每一個後續請求都使用同一個例項。"
最後,是transient:
state 即用即棄,也會造成a頁面賦了值,b頁面拿不到的情況
"在處理請求的應用中,在請求結束時會釋放暫時服務。 此生存期會產生每個請求的分配,因為每次都會解析和構建服務。"
寫在最後
不同的服務適用於不同的業務:
如果我是儲存使用者資料,顯然是scoped