[.NET 8.0] 從零開始理解Blazor WebAssembly——Program.cs
            Copyright Notice: This article is an original work licensed under the CC 4.0 BY-NC-ND license.
            If you wish to repost this article, please include the original source link and this copyright notice.
            
            Source link: https://v2know.com/article/1038
Code:
using BlazorEmpty;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using BlazorEmpty.Services;
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.Services.AddScoped<ProductService>();  // 註冊 ProductService
builder.RootComponents.Add<HeadOutlet>("head::after");
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
await builder.Build().RunAsync();
關鍵部分解釋
- 
	
using指令:Microsoft.AspNetCore.Components.Web和Microsoft.AspNetCore.Components.WebAssembly.Hosting是 Blazor WebAssembly 專案中常用的命名空間,提供 Blazor 所需的基本功能。BlazorApp是專案的命名空間,這裡它包含應用程式的根組件App。
 - 
	
WebAssemblyHostBuilder.CreateDefault(args):- 這是 Blazor WebAssembly 專案啟動的關鍵,它創建了一個 WebAssembly 的主機構建器。通過它,你可以配置應用程式的各種服務和組件。
 args是命令列參數,通常在啟動時傳遞。
 - 
	
builder.RootComponents.Add<App>("#app"):- 這行代碼將 
App組件作為應用的根組件註冊,並告訴 Blazor 將其渲染到 HTML 頁面中 ID 為#app的元素內。 App組件通常是 Blazor 應用的入口點,負責定義整個應用的佈局和導航。
 - 這行代碼將 
 - 
	
builder.Services.AddScoped:- 這裡註冊了一個服務,它為應用提供了 
HttpClient實例,並配置了基礎地址。HttpClient是 Blazor 應用與伺服器通信的重要工具。 AddScoped方法表示服務的生命週期是 "Scoped",在 Blazor WebAssembly 中,它的作用範圍是使用者會話期間,即在一次頁面加載後,HttpClient實例會被重用。
 - 這裡註冊了一個服務,它為應用提供了 
 - 
	
await builder.Build().RunAsync():Build()方法構建 WebAssembly 主機,它會應用所有之前配置的服務和設定。RunAsync()方法啟動應用程式,並保持其在瀏覽器中運行。
 
總結
Program.cs文件的主要作用是在 Blazor 專案中配置應用的啟動行為,註冊組件和服務。- 你可以在這裡自訂服務,比如添加其他依賴注入的服務,配置 API 地址,或為 Blazor 應用添加中介軟體。
 
詳細介紹
在 Blazor WebAssembly 專案中,HeadOutlet 元件的主要用途是動態更新 HTML <head> 部分的內容,比如頁面標題(<title>)、元數據(<meta>)、以及連結標籤(<link>)等。
builder.RootComponents.Add<HeadOutlet>("head::after");
這行代碼將 HeadOutlet 元件插入到 HTML 的 <head> 部分,允許你在應用程式運行時動態更新頁面頭部的內容。
例如:
@page "/example"
<HeadContent>
    <meta name="description" content="This is an example page." />
    <link rel="stylesheet" href="https://example.com/styles.css" />
</HeadContent>
<PageTitle>Example Page</PageTitle>
<h3>This is an example page</h3>
如果你在 Program.cs 中不增加這行代碼:
builder.RootComponents.Add<App>("#app");
那麼 Blazor 應用的根組件 App.razor 將不會被使用,那麼整個應用的路由功能也將不存在。
這是因為 Blazor 應用的路由系統是由根組件 App.razor 控制的,App.razor 負責定義應用的路由和頁面導航。
額外補充
builder.Services.AddScoped<ProductService>();
builder.Services 是一個 服務容器(Service Collection),它用來配置應用中的服務。
AddScoped<ProductService>() 的作用是將 ProductService 服務以 "scoped"(範圍) 的生命周期註冊到服務容器中,並在應用中使用依賴注入來解析這個服務。
Scoped 生命周期
當你使用 AddScoped 方法註冊服務時,這個服務的實例將在一個 "作用範圍" 內保持相同。具體來說:
- 在 Blazor WebAssembly 中,scoped 服務的作用範圍是整個應用程式的瀏覽器會話。在一個瀏覽器頁面中,該服務會保持單一實例。
 - 在 Blazor Server 或 ASP.NET Core 應用中,scoped 服務的作用範圍是每個HTTP 請求。對於同一個請求,該服務的實例是唯一的,但不同的請求會創建新的實例。
 
ProductService 是應用中的一個服務。(我寫的)
具體我在項目内新建了一個叫Services的文件夾,裏面寫了個ProductService.cs:
using BlazorEmpty.Models;
namespace BlazorEmpty.Services
{
    public class ProductService
    {
        public async Task<Product> LoadProductAsync(int id)
        {
            // 模擬數據加載,等待一秒鐘來模擬服務器延遲
            await Task.Delay(1000);
            // 返回模擬的產品數據
            return new Product
            {
                Id = id,
                Name = $"Product {id}",
                Description = "This is a description of the product."
            };
        }
    }
}
内容是啥並不重要。它還用了我創建的/Models/Product.cs:
namespace BlazorEmpty.Models
{
    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
    }
}
至於AddScoped<ProductService>()的行爲實際上就是把ProductService.cs放到了啓動項裏面。
全局都被聲明了這個類。
至於它的生命周期得看你用的是Blazor WebAssembly還是Blazor Server 。
還有,這個類不可能是靜態類,如果你寫靜態類IDE會直接提醒你編譯不會通過。
This article was last edited at