共用方式為


.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 資源底下所列的自定義命令。 在儀錶板的 [資源] 頁面上,選取 [動作] 欄底下的省略號按鈕:

.NET Aspire 儀錶板:Redis 顯示自定義命令的快取資源。

上圖顯示已新增至 資源的 Redis 命令。 圖示會顯示為兔子交叉,表示正在清除相依資源的速度。

選取 [清除快取] 命令,以清除 Redis 資源的快取。 命令應能順利執行,快取也會被清除。

.NET Aspire 儀錶板:Redis 執行自定義命令的快取資源。

另請參閱