-
I'm stitching together different snippets from multiple sources (discussions, twitter, reddit and so on) and I feel I'm getting closer and closer to get my application being fully built on Aspire despite many components not being super friendly to its model. Now I'm at the stage that I want to run a console application we use to initialize and seed our database. This operation is idempotent, so I don't mind adding it to the AppHost. Unfortunately, it needs the connection string to the database to be passed as an argument and I can't find a way to get it. using AppHost.Extensions;
using Projects;
var builder = DistributedApplication.CreateBuilder(args);
var adminUiClientId = builder.AddParameter("AdminUiClient");
var adminUiClientSecret = builder.AddParameter("AdminUiClientSecret");
var adminUiLicenseKey = builder.AddParameter("AdminUiLicenseKey");
var sqlPasswordResource = builder.AddParameter("SqlServerPassword");
var mssql = builder.AddSqlServer("db", sqlPasswordResource)
.PublishAsConnectionString()
.WithHealthCheck()
.WithDataVolume();
var db = mssql.AddDatabase("Database", "identity-manager")
.AddConnectionStringData(new Dictionary<string, object>
{
["MultipleActiveResultSets"] = true,
["Encrypt"] = false
}); // source: https://github.com/dotnet/aspire/discussions/3605
var legacyDb = mssql.AddDatabase("LegacyDatabase", "legacy")
.AddConnectionStringData(new Dictionary<string, object>
{
["MultipleActiveResultSets"] = true,
["Encrypt"] = false
});
var legacy = builder.AddProject<LegacyAPI>("legacy", "https")
.WaitFor(mssql) // source: https://github.com/davidfowl/WaitForDependenciesAspire
.WithReference(db);
var auth = builder.AddProject<AuthService>("auth", "https")
.WaitFor(mssql)
.WithReference(db)
.WithReference(legacyDb);
const string protocol = "https";
var dbOpsRunner = builder.AddProject("dbOpsRunner", "../DatabaseOpsRunner/DatabaseOpsRunner.csproj")
.WaitFor(mssql)
.WithArgs(["apply", "all", $"{db}"]) // insert connection string here
.WithEnvironment("ADMINUI__ADMINUICLIENTID", adminUiClientId)
.WithEnvironment("ADMINUI__UIURL", "https://localhost:7089") // add endpoint to auth
.WithEnvironment("ADMINUI__AUTHORITYURL", auth.GetEndpoint(protocol))
.WithEnvironment("ADMINUI__LICENSEKEY", adminUiLicenseKey);
EndpointReference adminEndpoint = default!;
var admin = builder.AddProject<Admin>("admin", "https")
.WaitForCompletion(dbOpsRunner)
.WaitFor(mssql)
.WithEnvironment("AdminUi__AdminUiClientId", adminUiClientId)
.WithEnvironment("AdminUi__AdminUiClientSecret", adminUiClientSecret)
.WithEnvironment("AdminUi__LicenseKey", adminUiLicenseKey)
.WithEnvironment("AdminUi__AuthorityUrl", auth.GetEndpoint(protocol))
.WithEnvironment("AdminUi__UiUrl", () => adminEndpoint.Url)
.WithReference(db);
adminEndpoint = admin.GetEndpoint(protocol);
// source: https://github.com/davidfowl/AspireYarp
// builder.AddYarp("login")
// .Route("legacy", legacy, path: "/accounts", preservePath: true)
// .Route("auth", auth, path: "/");
// .WithHttpEndpoint(port: 8001)
// .WithReference(auth)
// .LoadFromConfiguration("ReverseProxy");
builder.Build().Run(); I tried the following: .WithArgs(["apply", "all", $"{db}"])
// Result: the whole object gets printed out. .WithArgs(["apply", "all", $"{await db.Resource.GetConnectionStringAsync()}"])
// Result:
Unhandled exception. System.InvalidOperationException: The endpoint `tcp` is not allocated for the resource `db`.
at Aspire.Hosting.ApplicationModel.EndpointReference.get_AllocatedEndpoint() in /_/src/Aspire.Hosting/ApplicationModel/EndpointReference.cs:line 107
at Aspire.Hosting.ApplicationModel.EndpointReference.get_Port() in /_/src/Aspire.Hosting/ApplicationModel/EndpointReference.cs:line 79
at Aspire.Hosting.ApplicationModel.EndpointReferenceExpression.GetValueAsync(CancellationToken cancellationToken) in /_/src/Aspire.Hosting/ApplicationModel/EndpointReference.cs:line 179
at Aspire.Hosting.ApplicationModel.ReferenceExpression.GetValueAsync(CancellationToken cancellationToken) in /_/src/Aspire.Hosting/ApplicationModel/ReferenceExpression.cs:line 66
at Aspire.Hosting.ApplicationModel.ReferenceExpression.GetValueAsync(CancellationToken cancellationToken) in /_/src/Aspire.Hosting/ApplicationModel/ReferenceExpression.cs:line 66
at Aspire.Hosting.ApplicationModel.ReferenceExpression.GetValueAsync(CancellationToken cancellationToken) in /_/src/Aspire.Hosting/ApplicationModel/ReferenceExpression.cs:line 66
at Program.<Main>$(String[] args) in C:\Development\App\tools\AppHost\Program.cs:line 42
at Program.<Main>(String[] args)
Process finished with exit code -532,462,766. Another issue I'm having is passing the endpoint to a service to the console app. The tricky part is that I want the service to wait for the console app to terminate before it starts. For now I have hardcoded the port number. See
|
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 14 replies
-
It's not intuitive how you'd make this work: .WithArgs(context =>
{
context.Args.Add("apply");
context.Args.Add("all");
context.Args.Add(new ConnectionStringReference(db.Resource, optional: false)));
}) We need to add the string interpolation overload to adding args.
I'm not fully understanding this. You want the console app to terminate before which service starts? |
Beta Was this translation helpful? Give feedback.
It's not intuitive how you'd make this work:
We need to add the string interpolation overload to adding args.
I'm not fully understanding this. You want the console app to terminate before which service starts?