.NET .NET Aspire 中的自定義資源命令
.NET .NET Aspire 應用程式模型中 中的每個資源都會以 IResource 表示,當新增至 分散式應用程式產生器時,它是 IResourceBuilder<T> 介面的泛型型別參數。 您可以使用 資源產生器 API 來鏈結呼叫、設定基礎資源,在某些情況下,您可能會想要將自定義命令新增至資源。 建立自定義命令的一些常見案例可能是執行資料庫移轉或植入/重設資料庫。 在本文中,您將瞭解如何將自定義命令新增至清除快取的 Redis 資源。
重要
這些 .NET.NET Aspire 儀錶板 命令只能在本機執行儀錶板時使用。 在 Azure Container Apps中執行儀錶板時無法使用。
將自訂命令新增至資源
從 .NET建立新的 .NET Aspire 入門應用程式開始。 若要從此樣本建立解決方案,請遵循 快速入門:建置您的第一個 .NET.NET Aspire 解決方案。 建立此解決方案之後,將名為 RedisResourceBuilderExtensions.cs 的新類別新增至 應用程式主專案。 以下列程式代碼取代檔案的內容:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Logging;
using StackExchange.Redis;
namespace Aspire.Hosting;
internal static class RedisResourceBuilderExtensions
{
public static IResourceBuilder<RedisResource> WithClearCommand(
this IResourceBuilder<RedisResource> builder)
{
builder.WithCommand(
name: "clear-cache",
displayName: "Clear Cache",
executeCommand: context => OnRunClearCacheCommandAsync(builder, context),
updateState: OnUpdateResourceState,
iconName: "AnimalRabbitOff",
iconVariant: IconVariant.Filled);
return builder;
}
private static async Task<ExecuteCommandResult> OnRunClearCacheCommandAsync(
IResourceBuilder<RedisResource> builder,
ExecuteCommandContext context)
{
var connectionString = await builder.Resource.GetConnectionStringAsync() ??
throw new InvalidOperationException(
$"Unable to get the '{context.ResourceName}' connection string.");
await using var connection = ConnectionMultiplexer.Connect(connectionString);
var database = connection.GetDatabase();
await database.ExecuteAsync("FLUSHALL");
return CommandResults.Success();
}
private static ResourceCommandState OnUpdateResourceState(
UpdateCommandStateContext context)
{
var logger = context.ServiceProvider.GetRequiredService<ILogger<Program>>();
if (logger.IsEnabled(LogLevel.Information))
{
logger.LogInformation(
"Updating resource state: {ResourceSnapshot}",
context.ResourceSnapshot);
}
return context.ResourceSnapshot.HealthStatus is HealthStatus.Healthy
? ResourceCommandState.Enabled
: ResourceCommandState.Disabled;
}
}
上述程式代碼:
- 共用 Aspire.Hosting 命名空間,讓應用程式主專案可以看到它。
-
static class
的目的是使其可以包含擴充方法。 - 它會定義名為
WithClearCommand
的單一擴充方法,並擴充IResourceBuilder<RedisResource>
介面。 -
WithClearCommand
方法會註冊名為clear-cache
的命令,以清除 Redis 資源的快取。 -
WithClearCommand
方法會傳回IResourceBuilder<RedisResource>
實例以允許鏈結。
WithCommand
API 會將適當的批註新增至資源,這些批註會在 .NET.NET Aspire 儀錶板中取用。 儀錶板會使用這些批注在UI中轉譯命令。 在深入瞭解這些詳細數據之前,讓我們先確定您先瞭解 WithCommand
方法的參數:
-
name
:要叫用的命令名稱。 -
displayName
:要顯示在儀錶板中的命令名稱。 -
executeCommand
:叫用命令時要運行的Func<ExecuteCommandContext, Task<ExecuteCommandResult>>
,也就是實作命令邏輯的位置所在。 -
updateState
:調用Func<UpdateCommandStateContext, ResourceCommandState>
回呼函式,以判斷命令狀態的「已啟用」狀態,用來啟用或停用控制面板中的命令。 -
iconName
:要顯示在儀錶板中的圖示名稱。 此圖示為選用,但當您提供此圖示時,它應該是有效的 Fluent UI Blazor 圖示名稱。 -
iconVariant
:儀錶板中要顯示的圖示變體,有效選項有Regular
(預設)或Filled
。
執行命令邏輯
executeCommand
代理是實作命令邏輯的地方。 此參數定義為 Func<ExecuteCommandContext, Task<ExecuteCommandResult>>
。
ExecuteCommandContext
提供下列屬性:
-
ExecuteCommandContext.ServiceProvider
:用來解析服務的IServiceProvider
實例。 -
ExecuteCommandContext.ResourceName
:執行命令的資源實例名稱。 -
ExecuteCommandContext.CancellationToken
:用來取消命令執行的 CancellationToken。
在前一個範例中,executeCommand
委派被實作為 async
方法,用來清除 Redis 資源的快取。 它會委派給名為 OnRunClearCacheCommandAsync
的類別範圍函式,來執行實際的快取清除。 請考慮下列程式代碼:
private static async Task<ExecuteCommandResult> OnRunClearCacheCommandAsync(
IResourceBuilder<RedisResource> builder,
ExecuteCommandContext context)
{
var connectionString = await builder.Resource.GetConnectionStringAsync() ??
throw new InvalidOperationException(
$"Unable to get the '{context.ResourceName}' connection string.");
await using var connection = ConnectionMultiplexer.Connect(connectionString);
var database = connection.GetDatabase();
await database.ExecuteAsync("FLUSHALL");
return CommandResults.Success();
}
上述程式代碼:
- 從 Redis 資源擷取連接字串。
- 連接到 Redis 實例。
- 獲取資料庫實例。
- 執行
FLUSHALL
命令以清除快取。 - 傳回
CommandResults.Success()
實例,表示命令成功。
更新命令狀態邏輯
updateState
代理是用來判定命令狀態的地方。 此參數定義為 Func<UpdateCommandStateContext, ResourceCommandState>
。
UpdateCommandStateContext
提供下列屬性:
-
UpdateCommandStateContext.ServiceProvider
:用來解析服務的IServiceProvider
實例。 -
UpdateCommandStateContext.ResourceSnapshot
:執行命令的資源實例快照集。
不可變的快照集是 CustomResourceSnapshot
實例,它會公開有關資源實例的各種重要詳細數據。 請考慮下列程式代碼:
private static ResourceCommandState OnUpdateResourceState(
UpdateCommandStateContext context)
{
var logger = context.ServiceProvider.GetRequiredService<ILogger<Program>>();
if (logger.IsEnabled(LogLevel.Information))
{
logger.LogInformation(
"Updating resource state: {ResourceSnapshot}",
context.ResourceSnapshot);
}
return context.ResourceSnapshot.HealthStatus is HealthStatus.Healthy
? ResourceCommandState.Enabled
: ResourceCommandState.Disabled;
}
上述程式代碼:
- 從服務提供者擷取記錄器實例。
- 記錄資源快照詳情。
- 如果資源狀況良好,則傳回
ResourceCommandState.Enabled
;否則,它會傳回ResourceCommandState.Disabled
。
測試自定義命令
若要測試自訂命令,請更新應用程式主機專案的 Program.cs 檔案,以包含下列程式代碼:
var builder = DistributedApplication.CreateBuilder(args);
var cache = builder.AddRedis("cache")
.WithClearCommand();
var apiService = builder.AddProject<Projects.AspireApp_ApiService>("apiservice");
builder.AddProject<Projects.AspireApp_Web>("webfrontend")
.WithExternalHttpEndpoints()
.WithReference(cache)
.WaitFor(cache)
.WithReference(apiService)
.WaitFor(apiService);
builder.Build().Run();
上述程式代碼會呼叫 WithClearCommand
擴充方法,將自定義命令新增至 Redis 資源。 執行應用程式並流覽至 .NET.NET Aspire 儀錶板。 您應該會看到 Redis 資源底下所列的自定義命令。 在儀錶板的 [資源] 頁面上,選取 [動作] 欄底下的省略號按鈕:
上圖顯示已新增至 資源的 Redis 命令。 圖示會顯示為兔子交叉,表示正在清除相依資源的速度。
選取 [清除快取] 命令,以清除 Redis 資源的快取。 命令應能順利執行,快取也會被清除。