Created
September 4, 2025 04:54
-
-
Save Meir017/ba5468f65aaaf506f9c5b75df5edeef0 to your computer and use it in GitHub Desktop.
aspire vibed interaction service usage
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Microsoft.Extensions.DependencyInjection; | |
using Microsoft.Extensions.Logging; | |
using Aspire.Hosting; | |
#pragma warning disable ASPIREINTERACTION001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. | |
var builder = DistributedApplication.CreateBuilder(args); | |
var apiService = builder.AddProject<Projects.lcnc_aspire_demo_ApiService>("apiservice") | |
.WithHttpHealthCheck("/health") | |
.WithCommand("database-migration", "Database Migration Wizard", async context => | |
{ | |
var interactionService = context.ServiceProvider.GetRequiredService<IInteractionService>(); | |
var loggerService = context.ServiceProvider.GetRequiredService<ResourceLoggerService>(); | |
var logger = loggerService.GetLogger("apiservice"); | |
if (!interactionService.IsAvailable) | |
{ | |
return CommandResults.Failure("Interaction service is not available"); | |
} | |
try | |
{ | |
// Step 1: Welcome message (Dashboard only) | |
if (interactionService.IsAvailable) | |
{ | |
try | |
{ | |
await interactionService.PromptMessageBoxAsync( | |
"Database Migration Wizard", | |
""" | |
# π Welcome to the Database Migration Wizard! | |
This wizard will guide you through: | |
- **Database connection configuration** | |
- **Migration script selection** | |
- **Backup creation (optional)** | |
- **Migration execution** | |
Let's get started! π | |
""", | |
new MessageBoxInteractionOptions | |
{ | |
EnableMessageMarkdown = true, | |
PrimaryButtonText = "Let's Go!" | |
}); | |
} | |
catch | |
{ | |
// Dashboard-only feature, ignore in CLI | |
} | |
} | |
// Step 2: Collect database configuration | |
var databaseInputs = new List<InteractionInput> | |
{ | |
new() | |
{ | |
Label = "Database Server", | |
InputType = InputType.Text, | |
Required = true, | |
Placeholder = "localhost" | |
}, | |
new() | |
{ | |
Label = "Database Name", | |
InputType = InputType.Text, | |
Required = true, | |
Placeholder = "lcnc_demo_db" | |
}, | |
new() | |
{ | |
Label = "Username", | |
InputType = InputType.Text, | |
Required = true, | |
Placeholder = "sa" | |
}, | |
new() | |
{ | |
Label = "Password", | |
InputType = InputType.SecretText, | |
Required = true, | |
Placeholder = "Enter database password" | |
}, | |
new() | |
{ | |
Label = "Environment", | |
InputType = InputType.Choice, | |
Required = true, | |
Options = | |
[ | |
new("development", "Development"), | |
new("staging", "Staging"), | |
new("production", "Production") | |
] | |
} | |
}; | |
var dbConfigResult = await interactionService.PromptInputsAsync( | |
title: "Database Configuration", | |
message: "Configure your database connection settings:", | |
inputs: databaseInputs, | |
options: new InputsDialogInteractionOptions | |
{ | |
ValidationCallback = async context => | |
{ | |
var serverInput = context.Inputs.FirstOrDefault(i => i.Label == "Database Server"); | |
var passwordInput = context.Inputs.FirstOrDefault(i => i.Label == "Password"); | |
if (string.IsNullOrWhiteSpace(serverInput?.Value)) | |
{ | |
context.AddValidationError(serverInput!, "Database server cannot be empty"); | |
} | |
if (passwordInput?.Value is { Length: < 6 }) | |
{ | |
context.AddValidationError(passwordInput, "Password must be at least 6 characters long"); | |
} | |
await Task.CompletedTask; | |
} | |
}); | |
if (dbConfigResult.Canceled) | |
{ | |
return CommandResults.Failure("Database configuration canceled by user"); | |
} | |
var dbServer = dbConfigResult.Data![0].Value!; | |
var dbName = dbConfigResult.Data[1].Value!; | |
var username = dbConfigResult.Data[2].Value!; | |
var password = dbConfigResult.Data[3].Value!; | |
var environment = dbConfigResult.Data[4].Value!; | |
logger.LogInformation("Database configuration collected - Server: {Server}, Database: {Database}, Environment: {Environment}", | |
dbServer, dbName, environment); | |
// Step 3: Migration options | |
var migrationInputs = new List<InteractionInput> | |
{ | |
new() | |
{ | |
Label = "Migration Type", | |
InputType = InputType.Choice, | |
Required = true, | |
Options = | |
[ | |
new("schema", "Schema Changes Only"), | |
new("data", "Data Migration Only"), | |
new("full", "Full Migration (Schema + Data)") | |
] | |
}, | |
new() | |
{ | |
Label = "Create Backup", | |
InputType = InputType.Boolean, | |
Required = false | |
}, | |
new() | |
{ | |
Label = "Batch Size", | |
InputType = InputType.Number, | |
Required = false, | |
Placeholder = "1000" | |
} | |
}; | |
var migrationResult = await interactionService.PromptInputsAsync( | |
title: "Migration Settings", | |
message: "Configure migration execution options:", | |
inputs: migrationInputs); | |
if (migrationResult.Canceled) | |
{ | |
return CommandResults.Failure("Migration settings canceled by user"); | |
} | |
var migrationType = migrationResult.Data![0].Value!; | |
var createBackup = bool.Parse(migrationResult.Data[1].Value ?? "false"); | |
var batchSize = int.Parse(migrationResult.Data[2].Value ?? "1000"); | |
// Step 4: Confirmation for production environment | |
if (environment == "production") | |
{ | |
try | |
{ | |
var prodConfirmation = await interactionService.PromptConfirmationAsync( | |
title: "β οΈ Production Environment Warning", | |
message: """ | |
You are about to run migrations on a **PRODUCTION** environment! | |
Please confirm: | |
- Database backup has been created | |
- Migration has been tested in staging | |
- You have approval for this change | |
**This action cannot be easily undone.** | |
""", | |
options: new MessageBoxInteractionOptions | |
{ | |
Intent = MessageIntent.Confirmation, | |
PrimaryButtonText = "Proceed with Migration", | |
SecondaryButtonText = "Cancel", | |
ShowSecondaryButton = true, | |
EnableMessageMarkdown = true | |
}); | |
if (!prodConfirmation.Data) | |
{ | |
return CommandResults.Failure("Production migration canceled for safety"); | |
} | |
} | |
catch | |
{ | |
// CLI context - prompt differently | |
var cliConfirm = await interactionService.PromptInputAsync( | |
title: "Production Environment Confirmation", | |
message: """ | |
You are about to run migrations on a PRODUCTION environment! | |
Please type 'CONFIRM' to proceed or anything else to cancel. | |
""", | |
new InteractionInput | |
{ | |
Label = "PRODUCTION ENVIRONMENT: Type 'CONFIRM' to proceed with migration:", | |
InputType = InputType.Text, | |
Required = true, | |
Placeholder = "CONFIRM" | |
}); | |
if (cliConfirm.Canceled || cliConfirm.Data?.Value != "CONFIRM") | |
{ | |
return CommandResults.Failure("Production migration not confirmed"); | |
} | |
} | |
} | |
// Step 5: Execute migration simulation | |
logger.LogInformation("Starting {MigrationType} migration for {Environment} environment...", | |
migrationType, environment); | |
if (createBackup) | |
{ | |
logger.LogInformation("Creating database backup..."); | |
await Task.Delay(2000); // Simulate backup | |
logger.LogInformation("β Database backup completed"); | |
} | |
// Simulate migration steps | |
var steps = migrationType switch | |
{ | |
"schema" => new[] { "Updating table schemas", "Creating indexes", "Updating constraints" }, | |
"data" => new[] { "Migrating user data", "Updating references", "Validating data integrity" }, | |
"full" => new[] { "Updating table schemas", "Creating indexes", "Migrating user data", "Updating references", "Validating data integrity" }, | |
_ => new[] { "Unknown migration type" } | |
}; | |
foreach (var step in steps) | |
{ | |
logger.LogInformation("π {Step}...", step); | |
await Task.Delay(1500); // Simulate work | |
logger.LogInformation("β {Step} completed", step); | |
} | |
// Step 6: Success notification | |
try | |
{ | |
await interactionService.PromptNotificationAsync( | |
title: "Migration Completed Successfully! π", | |
message: $"Database migration completed for {environment} environment with {steps.Length} steps executed.", | |
options: new NotificationInteractionOptions | |
{ | |
Intent = MessageIntent.Success, | |
LinkText = "View Migration Logs", | |
LinkUrl = "https://learn.microsoft.com/dotnet/aspire" | |
}); | |
} | |
catch | |
{ | |
// CLI context - just log | |
logger.LogInformation("π Migration completed successfully!"); | |
} | |
return CommandResults.Success(); | |
} | |
catch (Exception ex) | |
{ | |
logger.LogError(ex, "Migration failed: {Error}", ex.Message); | |
try | |
{ | |
await interactionService.PromptNotificationAsync( | |
title: "Migration Failed", | |
message: $"An error occurred during migration: {ex.Message}", | |
options: new NotificationInteractionOptions | |
{ | |
Intent = MessageIntent.Error, | |
LinkText = "Troubleshoot", | |
LinkUrl = "https://learn.microsoft.com/dotnet/aspire/troubleshoot" | |
}); | |
} | |
catch | |
{ | |
// CLI context - already logged | |
} | |
return CommandResults.Failure($"Migration failed: {ex.Message}"); | |
} | |
}); | |
builder.AddProject<Projects.lcnc_aspire_demo_Web>("webfrontend") | |
.WithExternalHttpEndpoints() | |
.WithHttpHealthCheck("/health") | |
.WithReference(apiService) | |
.WaitFor(apiService) | |
.WithCommand("deploy-config", "Deployment Configuration", async context => | |
{ | |
var interactionService = context.ServiceProvider.GetRequiredService<IInteractionService>(); | |
var loggerService = context.ServiceProvider.GetRequiredService<ResourceLoggerService>(); | |
var logger = loggerService.GetLogger("webfrontend"); | |
if (!interactionService.IsAvailable) | |
{ | |
return CommandResults.Failure("Interaction service is not available"); | |
} | |
// Complex deployment configuration wizard | |
var deployInputs = new List<InteractionInput> | |
{ | |
new() | |
{ | |
Label = "Deployment Target", | |
InputType = InputType.Choice, | |
Required = true, | |
Options = | |
[ | |
new("azure", "Azure App Service"), | |
new("docker", "Docker Container"), | |
new("k8s", "Kubernetes"), | |
new("iis", "IIS On-Premises") | |
] | |
}, | |
new() | |
{ | |
Label = "Scaling Mode", | |
InputType = InputType.Choice, | |
Required = true, | |
Options = | |
[ | |
new("manual", "Manual Scaling"), | |
new("auto", "Auto Scaling"), | |
new("scheduled", "Scheduled Scaling") | |
] | |
}, | |
new() | |
{ | |
Label = "Instance Count", | |
InputType = InputType.Number, | |
Required = true, | |
Placeholder = "2" | |
}, | |
new() | |
{ | |
Label = "Enable HTTPS", | |
InputType = InputType.Boolean, | |
Required = false | |
}, | |
new() | |
{ | |
Label = "API Key", | |
InputType = InputType.SecretText, | |
Required = false, | |
Placeholder = "Optional API key for external services" | |
} | |
}; | |
var deployResult = await interactionService.PromptInputsAsync( | |
title: "Web Frontend Deployment", | |
message: "Configure deployment settings for the web frontend:", | |
inputs: deployInputs); | |
if (deployResult.Canceled) | |
{ | |
return CommandResults.Failure("Deployment configuration canceled"); | |
} | |
var target = deployResult.Data![0].Value!; | |
var scaling = deployResult.Data[1].Value!; | |
var instances = int.Parse(deployResult.Data[2].Value ?? "1"); | |
var httpsEnabled = bool.Parse(deployResult.Data[3].Value ?? "false"); | |
var apiKey = deployResult.Data[4].Value; | |
logger.LogInformation("Deployment configured - Target: {Target}, Scaling: {Scaling}, Instances: {Instances}, HTTPS: {HTTPS}", | |
target, scaling, instances, httpsEnabled); | |
// Simulate deployment process | |
await Task.Delay(1000); | |
logger.LogInformation("π Deployment configuration saved successfully!"); | |
return CommandResults.Success(); | |
}); | |
builder.Build().Run(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment