Skip to content

βœ… Merge main into live #3674

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion docs/community-toolkit/hosting-postgresql-extensions.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: PostgreSQL hosting extensions
description: Learn how to use the .NET Aspire PostgreSQL extensions package which provides extra functionality to the .NET Aspire PostgreSQL hosting package.
ms.date: 03/04/2025
ms.date: 05/28/2025
---

# .NET Aspire Community Toolkit PostgreSQL hosting extensions
Expand All @@ -14,6 +14,7 @@ In this article, you learn about the .NET Aspire Community Toolkit PostgreSQL ho

This package provides the following features:

- [Adminer](https://adminer.org/) management UI
- [DbGate](https://dbgate.org/) management UI

## Hosting integration
Expand Down Expand Up @@ -46,4 +47,11 @@ var postgresServer = builder.AddPostgreSQL("PostgreSQL")
.WithDbGate();
```

To add the Adminer management UI to your PostgreSQL resource, call the `WithAdminer` method on the `PostgresServerResource` instance.

```csharp
var postgresServer = builder.AddPostgreSQL("PostgreSQL")
.WithAdminer();
```

This will add a new resource to the app host which will be available from the .NET Aspire dashboard.
10 changes: 9 additions & 1 deletion docs/community-toolkit/hosting-sqlserver-extensions.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: SQL Server hosting extensions
description: Learn how to use the .NET Aspire SQL Server extensions package which provides extra functionality to the .NET Aspire SQL Server hosting package.
ms.date: 03/04/2025
ms.date: 05/28/2025
---

# .NET Aspire Community Toolkit SQL Server hosting extensions
Expand All @@ -14,6 +14,7 @@ In this article, you learn about the .NET Aspire Community Toolkit SQL Server ho

This package provides the following features:

- [Adminer](https://adminer.org/) management UI
- [DbGate](https://dbgate.org/) management UI

## Hosting integration
Expand Down Expand Up @@ -46,4 +47,11 @@ var sqlserver = builder.AddSqlServer("sqlserver")
.WithDbGate();
```

To add the Adminer management UI to your SQL Server resource, call the `WithAdminer` method on the `SqlServerResourceBuilder` instance.

```csharp
var sqlserver = builder.AddSqlServer("sqlserver")
.WithAdminer();
```

This will add a new resource to the app host which will be available from the .NET Aspire dashboard.
106 changes: 5 additions & 101 deletions docs/database/includes/sql-app-host.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,7 @@ For more information, see [dotnet add package](/dotnet/core/tools/dotnet-add-pac

In your app host project, call <xref:Aspire.Hosting.SqlServerBuilderExtensions.AddSqlServer*> to add and return a SQL Server resource builder. Chain a call to the returned resource builder to <xref:Aspire.Hosting.SqlServerBuilderExtensions.AddDatabase*>, to add SQL Server database resource.

```csharp
var builder = DistributedApplication.CreateBuilder(args);

var sql = builder.AddSqlServer("sql")
.WithLifetime(ContainerLifetime.Persistent);

var db = sql.AddDatabase("database");

builder.AddProject<Projects.ExampleProject>()
.WithReference(db)
.WaitFor(db);

// After adding all resources, run the app...
```
:::code language="csharp" source="../snippets/sql-server-integration/AspireApp.AppHost/AppHost.cs":::

> [!NOTE]
> The SQL Server container is slow to start, so it's best to use a _persistent_ lifetime to avoid unnecessary restarts. For more information, see [Container resource lifetime](../../fundamentals/orchestrate-resources.md#container-resource-lifetime).
Expand Down Expand Up @@ -81,74 +68,17 @@ IF
CREATE DATABASE [<QUOTED_DATABASE_NAME>];
```

<!-- TODO: Use xref here when available

To alter the default script, chain a call to the <xref:Aspire.Hosting.SqlServerBuilderExtensions.WithCreationScript*> method on the database resource builder:

-->

To alter the default script, chain a call to the `WithCreationScript` method on the database resource builder:

```csharp
var builder = DistributedApplication.CreateBuilder(args);

var sql = builder.AddSqlServer("sql")
.WithLifetime(ContainerLifetime.Persistent);

var databaseName = "app_db";
var creationScript = $$"""
IF DB_ID('{{databaseName}}') IS NULL
CREATE DATABASE [{{databaseName}}];
GO

-- Use the database
USE [{{databaseName}}];
GO

-- Create the todos table
CREATE TABLE todos (
id INT PRIMARY KEY AUTO_INCREMENT, -- Unique ID for each todo
title VARCHAR(255) NOT NULL, -- Short description of the task
description TEXT, -- Optional detailed description
is_completed BOOLEAN DEFAULT FALSE, -- Completion status
due_date DATE, -- Optional due date
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
GO

""";

var db = sql.AddDatabase(databaseName)
.WithCreationScript(creationScript);

builder.AddProject<Projects.ExampleProject>()
.WithReference(db)
.WaitFor(db);

// After adding all resources, run the app...
```
:::code language="csharp" source="../snippets/sql-server-creation-script/AspireApp.AppHost/AppHost.cs":::

The preceding example creates a database named `app_db` with a single `todos` table. The SQL script is executed when the database resource is created. The script is passed as a string to the `WithCreationScript` method, which is then executed in the context of the SQL Server resource.

### Add SQL Server resource with data volume

To add a data volume to the SQL Server resource, call the <xref:Aspire.Hosting.SqlServerBuilderExtensions.WithDataVolume*> method on the SQL Server resource:

```csharp
var builder = DistributedApplication.CreateBuilder(args);

var sql = builder.AddSqlServer("sql")
.WithDataVolume();

var db = sql.AddDatabase("database");

builder.AddProject<Projects.ExampleProject>()
.WithReference(db)
.WaitFor(db);

// After adding all resources, run the app...
```
:::code language="csharp" source="../snippets/sql-server-data-volume/AspireApp.AppHost/AppHost.cs":::

The data volume is used to persist the SQL Server data outside the lifecycle of its container. The data volume is mounted at the `/var/opt/mssql` path in the SQL Server container and when a `name` parameter isn't provided, the name is generated at random. For more information on data volumes and details on why they're preferred over [bind mounts](#add-sql-server-resource-with-data-bind-mount), see [Docker docs: Volumes](https://docs.docker.com/engine/storage/volumes).

Expand All @@ -159,20 +89,7 @@ The data volume is used to persist the SQL Server data outside the lifecycle of

To add a data bind mount to the SQL Server resource, call the <xref:Aspire.Hosting.SqlServerBuilderExtensions.WithDataBindMount*> method:

```csharp
var builder = DistributedApplication.CreateBuilder(args);

var sql = builder.AddSqlServer("sql")
.WithDataBindMount(source: @"C:\SqlServer\Data");

var db = sql.AddDatabase("database");

builder.AddProject<Projects.ExampleProject>()
.WithReference(db)
.WaitFor(db);

// After adding all resources, run the app...
```
:::code language="csharp" source="../snippets/sql-server-bind-mount/AspireApp.AppHost/AppHost.cs":::

[!INCLUDE [data-bind-mount-vs-volumes](../../includes/data-bind-mount-vs-volumes.md)]

Expand All @@ -182,20 +99,7 @@ Data bind mounts rely on the host machine's filesystem to persist the SQL Server

When you want to explicitly provide the password used by the container image, you can provide these credentials as parameters. Consider the following alternative example:

```csharp
var builder = DistributedApplication.CreateBuilder(args);

var password = builder.AddParameter("password", secret: true);

var sql = builder.AddSqlServer("sql", password);
var db = sql.AddDatabase("database");

builder.AddProject<Projects.ExampleProject>()
.WithReference(db)
.WaitFor(db);

// After adding all resources, run the app...
```
:::code language="csharp" source="../snippets/sql-server-parameters/AspireApp.AppHost/AppHost.cs":::

For more information on providing parameters, see [External parameters](../../fundamentals/external-parameters.md).

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"appHostPath": "../AspireApp.AppHost/AspireApp.AppHost.csproj"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
var builder = DistributedApplication.CreateBuilder(args);

var sql = builder.AddSqlServer("sql")
.WithDataBindMount(source: @"C:\SqlServer\Data");

var db = sql.AddDatabase("database");

builder.AddProject<Projects.AspireApp_ExampleProject>("exampleproject")
.WithReference(db)
.WaitFor(db);

// After adding all resources, run the app...

builder.Build().Run();
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">

<Sdk Name="Aspire.AppHost.Sdk" Version="9.3.0" />

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<UserSecretsId>ba7d27f9-faf2-4dc2-9910-fa27dbbfefe4</UserSecretsId>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Aspire.Hosting.AppHost" Version="9.3.0" />
<PackageReference Include="Aspire.Hosting.SqlServer" Version="9.3.0" />
<ProjectReference Include="../AspireApp.ExampleProject/AspireApp.ExampleProject.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:17260;http://localhost:15287",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"DOTNET_ENVIRONMENT": "Development",
"ASPIRE_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21100",
"ASPIRE_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22102"
}
},
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:15287",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"DOTNET_ENVIRONMENT": "Development",
"ASPIRE_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19061",
"ASPIRE_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20241"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Aspire.Hosting.Dcp": "Warning"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@AspireApp.ExampleProject_HostAddress = http://localhost:5108

GET {{AspireApp.ExampleProject_HostAddress}}/weatherforecast/
Accept: application/json

###
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

var app = builder.Build();

// Configure the HTTP request pipeline.

var summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};

app.MapGet("/weatherforecast", () =>
{
var forecast = Enumerable.Range(1, 5).Select(index =>
new WeatherForecast
(
DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
Random.Shared.Next(-20, 55),
summaries[Random.Shared.Next(summaries.Length)]
))
.ToArray();
return forecast;
});

app.Run();

record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
{
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
ο»Ώ{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "http://localhost:5108",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsAspireSharedProject>true</IsAspireSharedProject>
</PropertyGroup>

<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />

<PackageReference Include="Microsoft.Extensions.Http.Resilience" Version="9.4.0" />
<PackageReference Include="Microsoft.Extensions.ServiceDiscovery" Version="9.3.0" />
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.12.0" />
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.12.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.12.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.12.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" Version="1.12.0" />
</ItemGroup>

</Project>
Loading
Loading