今天要來介紹的是組態設定,也就是透過載入組態檔來取得值,使得外部能夠透過修改組態檔來影響程式的運作。
Blazor WebAssembly 預設會從應用程式中載入 wwwroot/appsettings.json
與 wwwroot/appsettings.{ENVIRONMENT}.json
組態檔,若想要載入這些檔名以外的組態也可以參考文章後面的方式自行添加。
由於範本專案並沒有包含組態檔,我們先來建立 wwwroot/appsettings.json
吧!
內容為:
// appsettings.json
{
"message": "Hello from config!",
"test": {
"message": "Hello2 from config!"
}
}
而元件只需要注入 IConfiguration
服務就可以取得組態資料了:
@* Day24Sample.razor *@
@page "/day24sample"
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration
<h3>Day24Sample</h3>
<p>@Configuration["message"]</p>
<p>@Configuration["test:message"]</p>
這樣就可以在畫面中看到從組態檔來的 Hello from config!
與 Hello2 from config!
文字,聰明的你看程式碼應該就能發現階層關係是以 :
來做劃分,如想要取得 test
物件下的 message
,則表示的字串為 test:message
,如此類推。
但你是否跟我一樣,對這種使用方式感覺有點美中不足,能不能像 .NET Core API
那樣,使用 services.Configure<TestConfig>(Configuration.GetSection("TestConfig"));
並透過 IOptions<TestConfig>
來取值?使得取得組態資料這件事情能夠透過強型別來管理?
遺憾的是我目前並沒有找到對應的方式來完成這件事情,但可以借鑑昨天的技巧,我們直接把組態內容與組態類別對應後註冊到 DI Container,這樣元件就可以透過注入該實體來取得組態內容,方法如:
建立一個組態類別:
// TestConfig.cs
public class TestConfig
{
public string Message { get; set; }
}
從組態取得對應內容並註冊到 DI Container:
builder.Services.AddSingleton(provider =>
{
var config = provider.GetService<IConfiguration>();
return config.GetSection("test").Get<TestConfig>();
});
之後我們就可以透過注入 TestConfig
來取得組態中 test
物件下的內容,是不是很簡單呀!
若想要新增其他的組態檔,則需要藉由 HTTP 的方式取得檔案,並透過 AddJsonStream
方法將串流加到 Configuration
,如下列方式:
var client = new HttpClient() { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) };
using var response = await client.GetAsync("mysettings.json");
using var stream = await response.Content.ReadAsStreamAsync();
builder.Configuration.AddJsonStream(stream);
需注意檔案一定要擺放在 wwwroot
目錄下,而如果你跟我一樣發現 AddJsonFile
這個方法,想說為什麼不像 .NET Core API
一樣直接用這個方法就好?那是因為我在使用時跟Blazor wasm AddJsonFile fails with error #21391發生了同樣的錯誤,可能未來能夠使用這種方式新增,但現在先暫時以上述方法增加組態檔吧!
以上就是組態設定的介紹,若想觀看本文的完整範例可以到範本程式碼 - day24。
感謝大家的閱讀,我們明天見。
參考資料
ASP.NET Core Blazor configuration
Using AppSettings in Blazor WebAssembly