dotnet / aspire

An opinionated, cloud ready stack for building observable, production ready, distributed applications in .NET
https://learn.microsoft.com/dotnet/aspire
MIT License
3.71k stars 426 forks source link

Add interfaces to PostgreSQL, Redis, and SqlServer Hosting Resources #6055

Open eerhardt opened 1 day ago

eerhardt commented 1 day ago

Background and Motivation

See https://github.com/dotnet/aspire/pull/5930#issuecomment-2381917879 for some of the context.

With

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

mitchdenny commented 1 day ago

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.

mitchdenny commented 1 day ago

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.