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會直接提醒你編譯不會通過。