Shiny.Aspire.Orleans.Hosting
1.0.0
Prefix Reserved
See the version list below for details.
dotnet add package Shiny.Aspire.Orleans.Hosting --version 1.0.0
NuGet\Install-Package Shiny.Aspire.Orleans.Hosting -Version 1.0.0
<PackageReference Include="Shiny.Aspire.Orleans.Hosting" Version="1.0.0" />
<PackageVersion Include="Shiny.Aspire.Orleans.Hosting" Version="1.0.0" />
<PackageReference Include="Shiny.Aspire.Orleans.Hosting" />
paket add Shiny.Aspire.Orleans.Hosting --version 1.0.0
#r "nuget: Shiny.Aspire.Orleans.Hosting, 1.0.0"
#:package Shiny.Aspire.Orleans.Hosting@1.0.0
#addin nuget:?package=Shiny.Aspire.Orleans.Hosting&version=1.0.0
#tool nuget:?package=Shiny.Aspire.Orleans.Hosting&version=1.0.0
Shiny Aspire Libraries
Zero-friction integration between .NET Aspire and Microsoft Orleans for ADO.NET storage backends. Automatically provisions Orleans database schemas and wires up clustering, grain persistence, and reminders from Aspire configuration — no manual SQL scripts or connection string plumbing required.
Also includes an Aspire hosting integration for Gluetun VPN containers.
Supported Databases
- PostgreSQL
- SQL Server
- MySQL
Packages
Quick Start
1. AppHost (Aspire Orchestrator)
Install Shiny.Aspire.Orleans.Hosting in your AppHost project.
using Shiny.Aspire.Orleans.Hosting;
var builder = DistributedApplication.CreateBuilder(args);
var db = builder.AddPostgres("pg")
.WithPgAdmin()
.AddDatabase("orleans-db");
var orleans = builder.AddOrleans("cluster")
.WithClustering(db)
.WithGrainStorage("Default", db)
.WithReminders(db)
.WithDatabaseSetup(db); // <-- creates all Orleans tables automatically
builder.AddProject<Projects.MySilo>("silo")
.WithReference(orleans)
.WaitFor(db);
builder.AddProject<Projects.MyApi>("api")
.WithReference(orleans.AsClient())
.WaitFor(db);
builder.Build().Run();
WithDatabaseSetup subscribes to Aspire's ResourceReadyEvent for the database resource. When the database container is up and accepting connections, it automatically executes the Orleans SQL schema scripts (clustering tables, persistence tables, reminders tables, stored procedures, and query registrations).
2. Orleans Silo
Install Shiny.Aspire.Orleans.Server in your silo project. The package registers Orleans provider builders for all supported database types (PostgresDatabase, SqlServerDatabase, MySqlDatabase) via assembly-level [RegisterProvider] attributes. Orleans' ApplyConfiguration automatically resolves these providers from the Aspire-injected configuration.
Call silo.UseAdoNet() inside UseOrleans for discoverability — provider registration is automatic when the package is referenced.
using Shiny.Aspire.Orleans.Server;
var builder = WebApplication.CreateBuilder(args);
builder.UseOrleans(silo =>
{
silo.UseAdoNet();
});
var app = builder.Build();
app.Run();
Because the extension is on ISiloBuilder, you can compose it with other Orleans features:
using Shiny.Aspire.Orleans.Server;
builder.UseOrleans(silo =>
{
silo.UseAdoNet();
// add other silo configuration here
});
3. Orleans Client
Install Shiny.Aspire.Orleans.Client in your client project (e.g. an API gateway).
using Shiny.Aspire.Orleans.Client;
var builder = WebApplication.CreateBuilder(args);
builder.UseOrleansClient(client =>
{
client.UseAdoNetClient();
});
var app = builder.Build();
app.MapGet("/counter/{name}", async (string name, IClusterClient client) =>
{
var grain = client.GetGrain<ICounterGrain>(name);
var count = await grain.GetCount();
return Results.Ok(new { name, count });
});
app.Run();
By default, WithDatabaseSetup creates schemas for all Orleans features. You can limit this using the OrleansFeature flags enum:
// Only set up clustering and persistence tables (no reminders)
orleans.WithDatabaseSetup(db, OrleansFeature.Clustering | OrleansFeature.Persistence);
// Only set up clustering
orleans.WithDatabaseSetup(db, OrleansFeature.Clustering);
Available flags:
| Flag | Value | Description |
|---|---|---|
Clustering |
1 | Membership tables for silo discovery |
Persistence |
2 | Grain storage tables |
Reminders |
4 | Reminder tables |
All |
7 | All of the above (default) |
Using Different Databases
The database type is auto-detected from the Aspire resource. Just swap the resource builder:
// PostgreSQL
var db = builder.AddPostgres("pg").AddDatabase("orleans-db");
// SQL Server
var db = builder.AddSqlServer("sql").AddDatabase("orleans-db");
// MySQL
var db = builder.AddMySql("mysql").AddDatabase("orleans-db");
Everything else stays the same — the correct SQL scripts, connection provider, and ADO.NET invariant are selected automatically.
How It Works
Provider Registration
The Server and Client packages register Orleans provider builders via [assembly: RegisterProvider] attributes. When Orleans calls ApplyConfiguration, it reads the Aspire-injected configuration (e.g. Orleans:Clustering:ProviderType = "PostgresDatabase") and resolves the matching provider builder automatically. The provider builder maps the database type to the correct ADO.NET invariant and connection string.
Registered provider names:
| ProviderType | Invariant | Kinds |
|---|---|---|
PostgresDatabase |
Npgsql |
Clustering, GrainStorage, Reminders |
SqlServerDatabase |
Microsoft.Data.SqlClient |
Clustering, GrainStorage, Reminders |
MySqlDatabase |
MySql.Data.MySqlClient |
Clustering, GrainStorage, Reminders |
Configuration Flow
Aspire automatically injects configuration into your silo and client projects when you use .WithReference(orleans). The injected configuration looks like:
Orleans:Clustering:ProviderType = "PostgresDatabase"
Orleans:Clustering:ServiceKey = "orleans-db"
Orleans:GrainStorage:Default:ProviderType = "PostgresDatabase"
Orleans:GrainStorage:Default:ServiceKey = "orleans-db"
Orleans:Reminders:ProviderType = "PostgresDatabase"
Orleans:Reminders:ServiceKey = "orleans-db"
ConnectionStrings:orleans-db = "Host=...;Database=..."
Orleans' ApplyConfiguration reads these sections and delegates to the registered provider builders, which configure the ADO.NET providers (Npgsql, Microsoft.Data.SqlClient, or MySqlConnector) with the correct connection strings and invariants.
Schema Provisioning
WithDatabaseSetup runs embedded SQL scripts in order:
- Main — creates the
OrleansQuerytable (Orleans' query registry) - Clustering — creates
OrleansMembershipVersionTable,OrleansMembershipTable, and related stored procedures/functions - Persistence — creates the
OrleansStoragetable and related stored procedures/functions - Reminders — creates
OrleansRemindersTableand related stored procedures/functions
Scripts are executed when Aspire raises the ResourceReadyEvent for the database, ensuring the database is accepting connections before any schema setup runs.
Multiple Grain Storage Providers
The server package supports multiple named grain storage providers:
// AppHost
var orleans = builder.AddOrleans("cluster")
.WithClustering(db)
.WithGrainStorage("Default", db)
.WithGrainStorage("Archive", archiveDb)
.WithDatabaseSetup(db);
// Grain
public class MyGrain(
[PersistentState("state", "Default")] IPersistentState<MyState> state,
[PersistentState("archive", "Archive")] IPersistentState<ArchiveState> archive
) : Grain, IMyGrain { }
Sample
The samples/ directory contains a complete working example:
| Project | Description |
|---|---|
Sample.AppHost |
Aspire orchestrator wiring PostgreSQL + PgAdmin, Orleans cluster, API, Gluetun VPN |
Sample.Silo |
Orleans silo with ADO.NET providers |
Sample.Api |
HTTP API with counter and reminder endpoints via IClusterClient |
Sample.GrainInterfaces |
ICounterGrain and IReminderGrain interfaces |
Sample.Grains |
CounterGrain (persistent state) and ReminderGrain (ADO.NET reminders) |
Run the sample:
dotnet run --project samples/Sample.AppHost
Shiny.Aspire.Hosting.Gluetun
Aspire hosting integration for Gluetun, a lightweight VPN client container supporting multiple providers. Models Gluetun as a first-class Aspire resource and lets other containers route their traffic through the VPN tunnel.
Quick Start
Install Shiny.Aspire.Hosting.Gluetun in your AppHost project.
var builder = DistributedApplication.CreateBuilder(args);
var vpn = builder.AddGluetun("vpn")
.WithVpnProvider("mullvad")
.WithWireGuard(builder.AddParameter("wireguard-key", secret: true))
.WithServerCountries("US", "Canada");
var scraper = builder.AddContainer("scraper", "my-scraper")
.WithHttpEndpoint(targetPort: 8080);
vpn.WithRoutedContainer(scraper);
builder.Build().Run();
This creates a Gluetun VPN container with Mullvad WireGuard, then routes the scraper container's traffic through it. At runtime the scraper joins the Gluetun network namespace (--network container:vpn). On Docker Compose publish, routed containers get network_mode: "service:vpn" and their ports are transferred to the Gluetun service.
API Reference
AddGluetun
Creates a Gluetun container resource with NET_ADMIN capability and /dev/net/tun device access.
IResourceBuilder<GluetunResource> AddGluetun(
this IDistributedApplicationBuilder builder,
string name,
int? httpProxyPort = null,
int? shadowsocksPort = null)
The optional port parameters expose Gluetun's built-in HTTP proxy (default target 8888) and Shadowsocks proxy (default target 8388) endpoints.
VPN Provider Configuration
// Set the VPN service provider (required)
vpn.WithVpnProvider("mullvad");
// OpenVPN — string credentials
vpn.WithOpenVpn("username", "password");
// OpenVPN — Aspire parameter resources (recommended for secrets)
vpn.WithOpenVpn(
builder.AddParameter("openvpn-user"),
builder.AddParameter("openvpn-pass", secret: true));
// WireGuard — string key
vpn.WithWireGuard("my-private-key");
// WireGuard — Aspire parameter resource (recommended for secrets)
vpn.WithWireGuard(builder.AddParameter("wireguard-key", secret: true));
Server Selection
vpn.WithServerCountries("US", "Canada", "Germany");
vpn.WithServerCities("New York", "Toronto");
Values are comma-joined and set as SERVER_COUNTRIES / SERVER_CITIES environment variables.
Proxy Features
vpn.WithHttpProxy(); // enables Gluetun's built-in HTTP proxy (HTTPPROXY=on)
vpn.WithHttpProxy(false); // disables it (HTTPPROXY=off)
vpn.WithShadowsocks(); // enables Shadowsocks proxy (SHADOWSOCKS=on)
vpn.WithShadowsocks(false); // disables it (SHADOWSOCKS=off)
Network & Firewall
vpn.WithFirewallOutboundSubnets("10.0.0.0/8", "192.168.0.0/16");
vpn.WithTimezone("America/New_York");
Generic Environment Variables
Pass any Gluetun environment variable not covered by the typed methods:
vpn.WithGluetunEnvironment("DNS_ADDRESS", "1.1.1.1");
vpn.WithGluetunEnvironment("UPDATER_PERIOD", builder.AddParameter("updater-period"));
Routing Containers Through the VPN
vpn.WithRoutedContainer(scraper);
vpn.WithRoutedContainer(downloader);
Each call:
- Adds a
GluetunRoutedResourceAnnotationto the Gluetun resource - Sets
--network container:<vpn-name>runtime args on the routed container - On Docker Compose publish, sets
network_mode: "service:<vpn-name>"on the routed container and transfers its port mappings to the Gluetun service
You can route multiple containers through the same VPN.
Docker Compose Publish
When you publish with dotnet run --publisher manifest or Docker Compose, routed containers automatically get:
services:
vpn:
image: qmcgaw/gluetun:latest
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun
environment:
- VPN_SERVICE_PROVIDER=mullvad
- VPN_TYPE=wireguard
- WIREGUARD_PRIVATE_KEY=${wireguard-key}
- SERVER_COUNTRIES=US,Canada
ports:
- "8080:8080" # forwarded from scraper
scraper:
image: my-scraper
network_mode: "service:vpn"
# ports moved to vpn service
Supported VPN Providers
Gluetun supports 30+ VPN providers. See the Gluetun wiki for the full list and provider-specific environment variables. Use WithGluetunEnvironment for any provider-specific settings not covered by the typed methods.
Requirements
- .NET 10
- .NET Aspire 13.1+
- Microsoft Orleans 10.0+ (for Orleans packages only)
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Aspire.Hosting.MySql (>= 13.1.2)
- Aspire.Hosting.Orleans (>= 13.1.2)
- Aspire.Hosting.PostgreSQL (>= 13.1.2)
- Aspire.Hosting.SqlServer (>= 13.1.2)
- Microsoft.Data.SqlClient (>= 6.1.4)
- MySqlConnector (>= 2.5.0)
- Npgsql (>= 10.0.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.1-beta-0002 | 107 | 3/8/2026 |
| 1.0.0 | 129 | 3/8/2026 |
| 1.0.0-g71b2f25a22 | 99 | 3/8/2026 |
| 1.0.0-beta-0009 | 106 | 3/8/2026 |
| 1.0.0-beta-0008 | 103 | 3/7/2026 |
| 1.0.0-beta-0007 | 98 | 3/7/2026 |
| 1.0.0-beta-0006 | 112 | 2/26/2026 |
| 1.0.0-beta-0005 | 110 | 2/26/2026 |
| 1.0.0-beta-0004 | 107 | 2/26/2026 |
| 1.0.0-beta-0003 | 110 | 2/26/2026 |
| 1.0.0-beta-0002 | 110 | 2/26/2026 |
| 1.0.0-beta-0001 | 113 | 2/25/2026 |