Dela via


Anpassade resurskommandon i .NET.NET Aspire

Varje resurs i .NET.NET Aspire-appmodellen representeras som en IResource och när den läggs till i distribuerad programbyggareär det parametern av generisk typ för IResourceBuilder<T>-gränssnittet. Du använder resursverktyget API för att länka anrop, konfigurera den underliggande resursen och i vissa fall kanske du vill lägga till anpassade kommandon i resursen. Ett vanligt scenario för att skapa ett anpassat kommando kan vara att köra databasmigreringar eller seeding/återställa en databas. I den här artikeln får du lära dig hur du lägger till ett anpassat kommando i en Redis resurs som rensar cacheminnet.

Viktig

Dessa .NET.NET Aspire instrumentpanel kommandon är endast tillgängliga när du kör instrumentpanelen lokalt. De är inte tillgängliga när du kör instrumentpanelen i Azure Container Apps.

Lägga till anpassade kommandon till en resurs

Börja med att skapa en ny .NET.NET Aspire startapplikation från tillgängliga mallar. Om du vill skapa lösningen från den här mallen följer du snabbstarten : Skapa din första .NET.NET Aspire lösning. När du har skapat den här lösningen lägger du till en ny klass med namnet RedisResourceBuilderExtensions.cs i appvärdprojektet. Ersätt innehållet i filen med följande kod:

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;
    }
}

Föregående kod:

  • Delar Aspire.Hosting namnområde så att det är synligt för appvärdprojektet.
  • Det är en static class så att den kan innehålla tilläggsmetoder.
  • Den definierar en enda tilläggsmetod med namnet WithClearCommandoch utökar IResourceBuilder<RedisResource>-gränssnittet.
  • Metoden WithClearCommand registrerar ett kommando med namnet clear-cache som rensar cachen för den Redis resursen.
  • Metoden WithClearCommand returnerar IResourceBuilder<RedisResource>-instansen för att tillåta länkning.

WithCommand-API:et lägger till lämpliga anteckningar i resursen, vilka används i instrumentpanelerna för .NET.NET Aspire. Instrumentpanelen använder dessa anteckningar för att återge kommandot i användargränssnittet. Innan du går för långt in på den här informationen ska vi se till att du först förstår parametrarna för metoden WithCommand:

  • name: Namnet på kommandot som ska anropas.
  • displayName: Namnet på kommandot som ska visas på instrumentpanelen.
  • executeCommand: Func<ExecuteCommandContext, Task<ExecuteCommandResult>> som ska köras när kommandot anropas, där kommandologiken implementeras.
  • updateState: Återanropet Func<UpdateCommandStateContext, ResourceCommandState> anropas för att fastställa kommandots "aktiverade" tillstånd, som används för att aktivera eller inaktivera kommandot på instrumentpanelen.
  • iconName: Namnet på ikonen som ska visas på instrumentpanelen. Ikonen är valfri, men när du anger den bör den vara ett giltigt Fluent-användargränssnittet Blazor ikonnamn.
  • iconVariant: Varianten av ikonen som ska visas på instrumentpanelen, giltiga alternativ är Regular (standard) eller Filled.

Utför kommandologik

Delegeringen executeCommand är där kommandologiken implementeras. Den här parametern definieras som en Func<ExecuteCommandContext, Task<ExecuteCommandResult>>. ExecuteCommandContext innehåller följande egenskaper:

  • ExecuteCommandContext.ServiceProvider: Den IServiceProvider instans som används för att hantera tjänster.
  • ExecuteCommandContext.ResourceName: Namnet på resursinstansen som kommandot körs på.
  • ExecuteCommandContext.CancellationToken: Den CancellationToken som används för att avbryta kommandokörningen.

I föregående exempel implementeras executeCommand-ombudet som en async metod som rensar cachen för den Redis resursen. Den delegerar ut till en privat funktion inom klassen med namnet OnRunClearCacheCommandAsync för att faktiskt utföra cacherensningen. Överväg följande kod:

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

Föregående kod:

  • Hämtar anslutningssträngen från den Redis resursen.
  • Ansluter till Redis-instansen.
  • Hämtar databasinstansen.
  • Kör kommandot FLUSHALL för att rensa cacheminnet.
  • Returnerar en CommandResults.Success() instans som anger att kommandot lyckades.

Uppdatera kommandotillståndslogik

Det updateState ombudet är där kommandotillståndet bestäms. Den här parametern definieras som en Func<UpdateCommandStateContext, ResourceCommandState>. UpdateCommandStateContext innehåller följande egenskaper:

  • UpdateCommandStateContext.ServiceProvider: Den IServiceProvider instans som används för att hantera tjänster.
  • UpdateCommandStateContext.ResourceSnapshot: Ögonblicksbilden av resursinstansen som kommandot körs på.

Den oföränderliga ögonblicksbilden är en instans av CustomResourceSnapshot, som visar alla typer av värdefull information om resursinstansen. Överväg följande kod:

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;
}

Föregående kod:

  • Hämtar loggningsinstansen från tjänstleverantören.
  • Loggar information om resursögonblicksbilden.
  • Returnerar ResourceCommandState.Enabled om resursen är felfri. annars returneras ResourceCommandState.Disabled.

Testa det anpassade kommandot

Om du vill testa det anpassade kommandot uppdaterar du appvärdprojektets Program.cs-fil så att den innehåller följande kod:

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

Föregående kod anropar WithClearCommand-tilläggsmetoden för att lägga till det anpassade kommandot i den Redis resursen. Kör appen och navigera till instrumentpanelen .NET.NET Aspire. Du ska se det anpassade kommandot under resursen Redis. På sidan Resurser på instrumentpanelen väljer du ellipsknappen under kolumnen Actions:

.NET Aspire instrumentpanel: Redis cacheresurs med anpassat kommando som visas.

Föregående bild visar kommandot Clear cache som lades till i resursen Redis. Ikonen visas när en kanin korsar ut för att indikera att hastigheten på den beroende resursen rensas.

Välj kommandot Rensa cache för att rensa cachen för den Redis resursen. Kommandot ska köras korrekt och cachen ska rensas:

.NET Aspire instrumentpanel: Redis cacheresurs med anpassat kommando som körs.

Se även