(7/30)大家一起學Blazor:生命週期(Lifetime)

(7/30)大家一起學Blazor:生命週期(Lifetime)

自己建立的Service都必須在Startup.cs(Blazor Server)或Program.cs(Blazor WebAssemlby)註冊,但有些基本Service就不用自己做了。

最後更新 2021/12/13 下午9:38
StrayaWorker
預計閱讀 3 分鐘
分類
Blazor
專題
一起學Blazor系列
標籤
.NET C# ASP.NET Core Blazor

前面說過自己建立的 Service 都必須在 Program.cs 註冊,但有些基本 Service 就不用自己做了。

目前 Blazor 提供內建的 Service 有三個,分別為:

  1. HttpClient:處理 http 請求,生命週期為 Scoped(注意:只有 Blazor WebAssembly 有提供,Blazor Server 必須自己註冊)
  2. IJSRuntime:提供 JavaScript runtime 元件處理 JS 功能,Blazor WebAssembly 生命週期為 Singleton,Blazor Server 生命週期為 Scoped
  3. NavigationManager:處理路由導向和狀態,Blazor WebAssembly 生命週期為 Singleton,Blazor Server 生命週期為 Scoped

生命週期指的就是 Component 存活的時間,除了 SingletonScoped,還有一種 Transient

  1. Singleton 是指從程式啟動到結束都只會有一個實例,所有 Component 共用一個實例。
  2. Transient 則是每次使用該 Component 時,都會產生一個新實例。
  3. Scoped 較為特別,Blazor Server 跟 Blazor WebAssembly 模式不相同,Blazor Server 的 Scoped 是指每次 HTTP 請求都會產生一個新的實例,但 Component 之間透過 SingalR 傳遞不會產生,微軟文件說明「Blazor WebAssembly 目前沒有 DI 的概念,Scoped 相當於 Singleton」。

不過筆者當初看了上述說明也是很懵,直到看了一個影片用 GUID 示範後才有所明白,我們就來試試看。

首先建立一個介面 IGuidService,裡面只有一個型別為 string 的屬性 UId,接著建立類別 GuidService 並在建構函式中初始化屬性 UId 為 GUID 字串,再去 Program.cs 使用 AddTransient 註冊。

然後建立一個 Guid.razor Component,裡面只有三行分別定義路由、注入服務以及顯示 GUID 字串,因為這案例很簡單所以沒用到 ComponentBase,所以需要在 _Import.razor 加入 @using BlazorServer.Services,最後為了切換方便,在 NavMenu.razor 定義一組 NavLink 指向剛才建立的 Guid.razor

啟動後不論在 Post 及 Guid 頁面切換,或是重新載入頁面,都可以看到生成全新的一組 GUID,這就是 Transient 的特性:每次切換都產生新的實例。

接著將註冊方式改為 Singleton,可以看到就算重新載入網頁,也都是同一組 GUID,這就是 Singleton 的特性:程式啟動到結束都只會有一個實例。

最後將註冊方式改為 Scoped,切換到 Post 頁面再切回來,還是同一組 GUID,但重新載入頁面時就會產生新的一組,這就是 Scoped 的特性:每次產生 HTTP 請求都會有新的實例,Component 之間則不會產生新實例。

上述的例子是以 Blazor Server 進行,若以 Blazor WebAssembly 進行,則 Singleton 會產生跟 Blazor Server 不同的情況,原因就是 Blazor WebAssembly 沒有伺服器端,每次重新載入網頁都會將程式下載到瀏覽器,這是一個全新的 HTTP 請求,所以 SingletonScoped 都是只要一重新載入網頁就會產生新的實例。

註:筆者為了方便省略影片中某些內容,有興趣的人可以再研究

引用:

註:本文程式碼透過 .NET 6 + Visual Studio 2022 重構,可點選原文連結與重構後程式碼比較學習,謝謝閱讀,支持原作者

繼續探索

延伸閱讀

更多文章
同分類 / 同標籤 2021/12/25

(29/30)大家一起學Blazor:Blazor單元測試

開發一個系統最無聊的過程大概就是解決 Bug 了,尤其是那種嘗試對 null 物件取值的錯誤(`Object reference not set to an instance of an object.`),這應該是大部分人剛踏入程式設計領域最常碰到的問題,為了從枯燥的解決 Bug 過程解脫,這篇就來介紹`單元測試`。

繼續閱讀
同分類 / 同標籤 2021/12/25

(28/30)大家一起學Blazor:Policy-based authorization

之前有說到`ASP.NET Core Identity` 使用的是基於`Claim` 的驗證,其實`ASP.NET Core Identity` 有不同類型的授權方式,最簡單的`登入授權`、`角色授權`、`Claim 授權`,但上述幾種都是以一種方式實現:原則授權(`Policy-based authorization`)。

繼續閱讀