EKsumic's Blog

let today = new Beginning();

Click the left button to use the catalog.

OR

[.NET 8.0] 從零開始理解Blazor WebAssembly——Program.cs

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();

關鍵部分解釋

  1. using 指令

    • Microsoft.AspNetCore.Components.WebMicrosoft.AspNetCore.Components.WebAssembly.Hosting 是 Blazor WebAssembly 專案中常用的命名空間,提供 Blazor 所需的基本功能。
    • BlazorApp 是專案的命名空間,這裡它包含應用程式的根組件 App
  2. WebAssemblyHostBuilder.CreateDefault(args)

    • 這是 Blazor WebAssembly 專案啟動的關鍵,它創建了一個 WebAssembly 的主機構建器。通過它,你可以配置應用程式的各種服務和組件。
    • args 是命令列參數,通常在啟動時傳遞。
  3. builder.RootComponents.Add<App>("#app")

    • 這行代碼將 App 組件作為應用的根組件註冊,並告訴 Blazor 將其渲染到 HTML 頁面中 ID 為 #app 的元素內。
    • App 組件通常是 Blazor 應用的入口點,負責定義整個應用的佈局和導航。
  4. builder.Services.AddScoped

    • 這裡註冊了一個服務,它為應用提供了 HttpClient 實例,並配置了基礎地址。HttpClient 是 Blazor 應用與伺服器通信的重要工具。
    • AddScoped 方法表示服務的生命週期是 "Scoped",在 Blazor WebAssembly 中,它的作用範圍是使用者會話期間,即在一次頁面加載後,HttpClient 實例會被重用。
  5. 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 2024-09-06 17:21:51

* *