aspire
aspire copied to clipboard
Add interfaces to PostgreSQL, Redis, and SqlServer Hosting Resources
Background and Motivation
See https://github.com/dotnet/aspire/pull/5930#issuecomment-2381917879 for some of the context.
With
- Add Azure PostgreSQL managed identity (dotnet/aspire#5930)
- Support Managed Identity in Azure Cache for Redis (dotnet/aspire#5966)
- Update Azure Sql to use new API pattern (dotnet/aspire#5998)
We re-designed how resources that can be hosted in either a container or a managed Azure resource (ex. PostgreSQL, Redis, SqlServer) are added to the model.
Before
var redis = builder.AddRedis("redis")
.PublishAsAzureRedis();
After
var redis = builder.AddAzureRedis("redis")
.RunAsContainer();
The downside of this approach is composability of resources. Let's say I wanted to have a resource that depended on a Postgres database instance. With this change the implementor of that would need to have extensions for each cloud provider (unless they just allow any IResourceWithConnectionString).
Proposed API
namespace Aspire.Hosting.Redis;
public interface IRedisResource : IResourceWithConnectionString
{
}
namespace Aspire.Hosting.ApplicationModel;
public class RedisResource : IRedisResource {...}
namespace Aspire.Hosting.Azure;
public class AzureRedisCacheResource : IRedisResource {...}
namespace Aspire.Hosting.Postgres;
public interface IPostgresServerResource : IResourceWithConnectionString
{
}
namespace Aspire.Hosting.ApplicationModel;
public class PostgresServerResource : IPostgresServerResource {...}
namespace Aspire.Hosting.Azure;
public class AzurePostgresFlexibleServerResource : IPostgresServerResource {...}
namespace Aspire.Hosting.SqlServer;
public interface ISqlServerServerResource : IResourceWithConnectionString
{
}
namespace Aspire.Hosting.ApplicationModel;
public class SqlServerServerResource : ISqlServerServerResource {...}
namespace Aspire.Hosting.Azure;
public class AzureSqlServerServerResource : ISqlServerServerResource {...}
Usage Examples
var redis1 = builder.AddRedis("cache1");
UseRedis(redis1);
var redis2 = builder.AddAzureRedis("cache2");
UseRedis(redis2);
static void UseRedis(IResourceBuilder<IRedisResource> redis)
{
... get the connection string, or use the resource some other way
}
Alternative Designs
Risks
cc @davidfowl @mitchdenny
Yep - I think we need to do this otherwise we'll stifle reuse of some of these fundamental application building blocks. You'll end up with packages on NuGet that look like this:
MyAspireStuff.Postgres.Azure MyAspireStuff.Postgres.AWS
... only because there isn't a shared type for the Redis resources.
I'm adding it to the backlog for now. I don't think we block 9.0 for it but I think it would be nice to see in 9.x.
for sql-server I found the following way:
var sqlServer = builder.AddSqlServer("sql-server")
.WithDataVolume("data");
sqlServer.WithCommand("open-in-vscode", "Open in VS Code", async context =>
{
var rawConnectionString = await sqlServer.Resource.GetConnectionStringAsync();
if (string.IsNullOrEmpty(rawConnectionString))
{
return new ExecuteCommandResult
{
Success = false,
ErrorMessage = "Connection string is not available."
};
}
VsCode.OpenSqlServerInVsCode(rawConnectionString);
return new ExecuteCommandResult { Success = true };
});
and the magic:
using System.Diagnostics;
using Microsoft.Data.SqlClient;
namespace Prevention.SecurityForAI;
public class VsCode
{
public static void OpenSqlServerInVsCode(string rawConnectionString)
{
var connectionString = new SqlConnectionStringBuilder(rawConnectionString);
string server = Uri.EscapeDataString(connectionString.DataSource);
string database = Uri.EscapeDataString(connectionString.InitialCatalog);
string userId = Uri.EscapeDataString(connectionString.UserID);
string password = Uri.EscapeDataString(connectionString.Password);
var vscodeUri = new Uri($"vscode://ms-mssql.mssql/connect?server={server}&database={database}&authenticationType=SqlLogin&user={userId}&password={password}&trustServerCertificate=true");
var process = Process.Start(new ProcessStartInfo
{
FileName = vscodeUri.ToString(),
UseShellExecute = true
});
}
}
this requires the https://marketplace.visualstudio.com/items?itemName=ms-mssql.mssql VsCode extension
@eerhardt / @eerhardt / @davidfowl is this out-of-scope here? should I create a separate issue for this? Maybe having a VsCode extention point that can open UI extensions for specific container based resources
This issue is about a C# interface not a user interface 😅.
I’ve marked it as off topic, and yea you can file a new issue