A collection of helpers to integrate common services with .NET Aspire quickly and in a standardized way.
🏢 Enterprise Validation: Featured on GFT Technologies
Read the full article on the GFT Engineering Blog
MVFC.Aspire.Helperswas built to solve real local orchestration challenges at an enterprise scale. Featured by a global powerhouse in technology, this article details how the library simplifies configuring services like MongoDB, RabbitMQ, and Keycloak. Discover how these abstractions reduce developer cognitive load and enable Shift-Left Testing in complex environments.
Orchestrating a realistic local environment for .NET distributed applications usually means:
- Writing and maintaining multiple
docker-composefiles. - Copy‑pasting container definitions between projects.
- Manually wiring ports, connection strings and health checks.
- Repeating the same setup for every new service in every new solution.
.NET Aspire solves part of this problem by giving you a first‑class orchestration model in C#, but you still have to model each infrastructure dependency (Mongo, Redis, Keycloak, etc.) yourself.
MVFC.Aspire.Helpers packages capture this knowledge once and expose it as small, focused helpers:
- One line to add the resource (
AddXxx). - A few fluent methods to customize it (
WithDataVolume,WithDumps,WithSeeds,WithCommander, etc.). - A single
WithReference(...)call to link your projects to the resource with the right environment variables and dependencies.
The goal is simple: make your local environment as close as possible to production while keeping the developer experience clone → run.
All libraries follow the same convention:
AddXxx(...)— registers the infrastructure resource in theIDistributedApplicationBuilder.- Fluent methods (
WithDataVolume,WithDumps,WithSeeds, etc.) — customize the resource. project.WithReference(xxx)— links a project to the resource, automatically configuring:WaitFordependency.- Environment variables (connection strings, base URLs, etc.).
- Initialization actions (e.g. executing Mongo dumps).
Once you learn how one helper works, the others feel immediately familiar.
| Package | Service | Downloads |
|---|---|---|
| MVFC.Aspire.Helpers.CloudStorage | Google Cloud Storage (GCS emulator) | |
| MVFC.Aspire.Helpers.Mongo | MongoDB with Replica Set | |
| MVFC.Aspire.Helpers.GcpFirestore | Google Cloud Firestore (emulator) | |
| MVFC.Aspire.Helpers.GcpPubSub | Google Pub/Sub (emulator + UI) | |
| MVFC.Aspire.Helpers.GcpSpanner | Google Cloud Spanner (emulator) | |
| MVFC.Aspire.Helpers.Gotenberg | Gotenberg (PDF conversion) | |
| MVFC.Aspire.Helpers.WireMock | WireMock.Net (API mocking) | |
| MVFC.Aspire.Helpers.Mailpit | Mailpit (SMTP emulator) | |
| MVFC.Aspire.Helpers.RabbitMQ | RabbitMQ | |
| MVFC.Aspire.Helpers.Redis | Redis + Redis Commander | |
| MVFC.Aspire.Helpers.Keycloak | Keycloak | |
| MVFC.Aspire.Helpers.ApigeeEmulator | Apigee Emulator (API proxy) |
dotnet add package MVFC.Aspire.Helpers.CloudStorage
dotnet add package MVFC.Aspire.Helpers.Mongo
dotnet add package MVFC.Aspire.Helpers.GcpFirestore
dotnet add package MVFC.Aspire.Helpers.GcpPubSub
dotnet add package MVFC.Aspire.Helpers.GcpSpanner
dotnet add package MVFC.Aspire.Helpers.Gotenberg
dotnet add package MVFC.Aspire.Helpers.WireMock
dotnet add package MVFC.Aspire.Helpers.Mailpit
dotnet add package MVFC.Aspire.Helpers.RabbitMQ
dotnet add package MVFC.Aspire.Helpers.Redis
dotnet add package MVFC.Aspire.Helpers.Keycloak
dotnet add package MVFC.Aspire.Helpers.ApigeeEmulatorvar builder = DistributedApplication.CreateBuilder(args);
var cloudStorage = builder.AddCloudStorage("cloud-storage")
.WithBucketFolder("./bucket-data");
var mongo = builder.AddMongoReplicaSet("mongo")
.WithDumps(dumps);
var firestore = builder.AddGcpFirestore("gcp-firestore")
.WithFirestoreConfigs(firestoreConfig);
var pubSub = builder.AddGcpPubSub("gcp-pubsub")
.WithPubSubConfigs(pubSubConfig);
var spanner = builder.AddGcpSpanner("spanner")
.WithSpannerConfigs(spannerConfig);
var mailpit = builder.AddMailpit("mailpit");
var rabbitMQ = builder.AddRabbitMQ("rabbitmq")
.WithExchanges([new ExchangeConfig("test-exchange", "topic")])
.WithQueues([new QueueConfig(Name: "test-queue", ExchangeName: "test-exchange", RoutingKey: "test.*")])
.WithDataVolume("rabbit-mq");
var redis = builder.AddRedis("redis")
.WithCommander()
.WithDataVolume("redis-data");
var gotenberg = builder.AddGotenberg("gotenberg", port: 3000);
var keycloak = builder.AddKeycloak("keycloak")
.WithAdminCredentials("admin", "Admin@123")
.WithSeeds([new MyAppRealm()])
.WithDataVolume("key-cloak-data");
var wireMock = builder.AddWireMock("wireMock", port: 7070, configure: (server) => {
server.Endpoint("/api/test")
.WithDefaultBodyType(BodyType.String)
.OnGet<string>(() => ("OK", HttpStatusCode.OK, null));
});
var api = builder.AddProject<Projects.MyApi>("api");
var apigeeWorkspace = Path.Combine(Directory.GetCurrentDirectory(), "apigee-workspace");
var apigee = builder.AddApigeeEmulator("apigee-emulator")
.WithWorkspace(apigeeWorkspace, "health")
.WithEnvironment("local")
.WithBackend(api, "origin");
await builder.Build().RunAsync().ConfigureAwait(false);See playground/ for the full working example.
src/
MVFC.Aspire.Helpers.CloudStorage/
MVFC.Aspire.Helpers.GcpFirestore/
MVFC.Aspire.Helpers.GcpPubSub/
MVFC.Aspire.Helpers.GcpSpanner/
MVFC.Aspire.Helpers.Gotenberg/
MVFC.Aspire.Helpers.Keycloak/
MVFC.Aspire.Helpers.Mailpit/
MVFC.Aspire.Helpers.Mongo/
MVFC.Aspire.Helpers.RabbitMQ/
MVFC.Aspire.Helpers.Redis/
MVFC.Aspire.Helpers.WireMock/
MVFC.Aspire.Helpers.ApigeeEmulator/
tests/
MVFC.Aspire.Helpers.Tests/
playground/
MVFC.Aspire.Helpers.Playground.Api/
- .NET 9 or .NET 10
- Aspire.Hosting >= 9.5.0
- Docker running locally
See CONTRIBUTING.md.