Is Your Local Dev Environment a Mess?

.NET Aspire

How .NET Aspire Can Help

Aaron Stannard / October 16, 2025
North Houston .NET User Group

About Me

  • CEO @ Petabridge
  • Akka.NET co-founder
  • 20+ years of .NET (since 2005)
  • Chronic skeptic of hype
Aaron Stannard

The Hype Train ๐Ÿš‚

"If you follow Microsoft's big personalities on social media..."

You might think .NET Aspire is:

  • Curing cancer โŒ
  • Proving P=NP โŒ
  • Delivering nuclear fusion โŒ

Reality: It's a dev productivity tool. A really good one.

The New Developer Experience

Day 1: "Welcome! Let's get you set up..."

  1. Clone the repo โœ“
  2. Request database access... wait 3 days
  3. Schema is in another repo (undocumented)
  4. No seed data (ask Jim, he might know)
  5. Service A needs Service B (which needs Service C)
  6. Shared dev database (someone just truncated your table)
  7. Docker Compose from 2019 (doesn't work on ARM Macs)

Week 2: "Are you up and running yet?"

The Dependency Multiplication Problem

graph TB subgraph "Your 'Simple' App" WebApp[Web App] API1[User API] API2[Order API] API3[Payment API] end subgraph "External Dependencies" DB1[(User DB)] DB2[(Order DB)] Cache[Redis Cache] Queue[RabbitMQ] Storage[Blob Storage] end WebApp --> API1 WebApp --> API2 API1 --> DB1 API1 --> Cache API2 --> DB2 API2 --> Queue API2 --> API3 API3 --> Storage style WebApp fill:#ff6b6b style API1 fill:#ff6b6b style API2 fill:#ff6b6b style API3 fill:#ff6b6b

Each arrow = configuration + credentials + setup time + potential failure

We've Tried to Fix This Before...

Docker Compose

  • โœ“ Defines dependencies
  • โœ“ Somewhat portable
  • โœ— Version drift
  • โœ— Init scripts are fragile
  • โœ— No IDE integration
  • โœ— Debugging is painful

Shared Dev Environment

  • โœ“ One setup to rule them all
  • โœ“ "Real" data
  • โœ— Developers collision
  • โœ— Can't test breaking changes
  • โœ— Remote debugging
  • โœ— "Who broke dev?!"

The Developer's Dream

git clone โ†’ F5

That's it. That's the dream.

And for product owners:

New developer productive in hours, not weeks

Enter .NET Aspire

What it actually does (and doesn't do)

What is .NET Aspire?

.NET Aspire

A local orchestrator for distributed .NET apps

โœ… What It Is

  • Development orchestrator
  • Service discovery
  • Resource lifecycle management
  • Built-in observability
  • Integration test framework

โŒ What It's NOT

  • Production orchestrator
  • Kubernetes replacement
  • Cloud deployment solution
  • Container platform
  • Magic pixie dust

The F5 Experienceโ„ข


var builder = DistributedApplication.CreateBuilder(args);

var postgres = builder.AddPostgres("db")
    .WithDataVolume();  // Data survives restarts!

var app = builder.AddProject<Projects.MyApp>("app")
    .WithReference(postgres)
    .WithReplicas(3);  // Run 3 instances

builder.Build().Run();
    

That's it. Press F5. Everything starts.

How Aspire Works

graph TB subgraph "Your Code" AppHost[AppHost - Program.cs] end subgraph "Aspire Runtime" DCP[Developer Control Plane] Dashboard[Dashboard :18888] end subgraph "Resources" Services[Your Services] Docker[Containers - PostgreSQL, Redis, etc.] end AppHost -->|Defines| DCP DCP -->|Orchestrates| Services DCP -->|Manages| Docker Services -->|OpenTelemetry| Dashboard Docker -->|Logs| Dashboard style AppHost fill:#512BD4 style DCP fill:#42affa style Dashboard fill:#17b2c3

The Magic Ingredients

๐ŸŽฏ AppHost

Defines your app model
Service dependencies
Resource configuration

๐ŸŽฎ DCP

Orchestrates resources
Manages lifecycle
Service discovery

๐Ÿ“Š Dashboard

Logs & traces
Resource status
Environment vars

๐Ÿ”ง Integrations

PostgreSQL, Redis
RabbitMQ, Kafka
Azure services

All accessible with one F5 press

Demo Time

Let's see it in action with DrawTogether.NET

Demo: DrawTogether.NET

DrawTogether.NET

Real-world collaborative drawing application

  • SQL Server with EF Core migrations
  • Multiple service instances (clustering)
  • Akka.NET actor system
  • Persistent data volumes

What we'll see:

  1. F5 to launch everything
  2. Dashboard tour
  3. Multiple instances running
  4. Distributed debugging

What Just Happened?

Automatically Started:

  • SQL Server container
  • Created database
  • Ran EF migrations
  • Started 3 app instances
  • Configured service discovery
  • Set up observability

You Did:

  • Pressed F5

Time from git clone to running app: < 2 minutes

Going Deeper

Real code, real patterns

Real-World AppHost


var sqlServer = builder.AddSqlServer("sql", saPassword)
    .WithDataVolume();  // Persistent across restarts

var db = sqlServer.AddDatabase("DrawTogetherDb");

// Run migrations before app starts
var migrationService = builder
    .AddProject<Projects.MigrationService>("migrations")
    .WaitFor(db)
    .WithReference(db);

// Start app only after migrations complete
var app = builder.AddProject<Projects.DrawTogether>("app")
    .WithReplicas(3)
    .WithReference(db)
    .WaitForCompletion(migrationService);
  

Migration Service Pattern

Migration Service


// MigrationService/Program.cs
var context = services
  .GetRequiredService<AppDbContext>();

await context.Database
  .MigrateAsync();

await SeedData(context);

// Signal completion
app.Run();
      

Benefits

  • Migrations run once
  • Before app starts
  • Can seed data
  • Version controlled
  • Works with teams

โš ๏ธ Avoiding Vendor Lock-in

โŒ Don't: Aspire Client Packages in Your App


// In your app's Program.cs - AVOID THIS!
builder.AddServiceDefaults();
builder.AddSqlServerDbContext<AppContext>("sqldata");
builder.AddRedisCache("cache");

// Magic service discovery & config
// Tightly coupled to Aspire runtime
// How do you deploy without Aspire?
      

โœ… Do: Standard .NET Configuration


// In AppHost - this is fine!
var redis = builder.AddRedis("cache");
app.WithEnvironment("RedisConnection",
    redis.GetConnectionString());

// In your app's Program.cs - standard .NET
services.AddStackExchangeRedisCache(options =>
{
    options.Configuration = config["RedisConnection"];
});
      

Automatic OpenTelemetry Integration

Aspire Dashboard Logs

Structured Logs

Aspire Dashboard Traces

Distributed Traces

Aspire Dashboard Metrics

System & App Metrics

Zero Configuration
Just works out of the box

Integration Testing Revolution

Real dependencies, no mocks

Real DrawTogether.NET Test Fixture


[Test]
public async Task CanCreateGameSessionAndDraw()
{
    // Start DrawTogether with real SQL Server
    var appHost = await DistributedApplicationTestingBuilder
        .CreateAsync<DrawTogether_AppHost>();

    await using var app = await appHost.BuildAsync();
    await app.StartAsync();

    // Wait for SQL migrations to complete
    await app.WaitForResource("sqlserver")
        .WaitForHealthy();

    // Connect with real SignalR client
    var blazorApp = app.CreateHttpClient("drawtogether");
    var hubConnection = new HubConnectionBuilder()
        .WithUrl($"{blazorApp.BaseAddress}draw-hub")
        .Build();

    await hubConnection.StartAsync();

    // Real drawing operations, real database persistence
    await hubConnection.InvokeAsync("CreateSession", "TestRoom");
    await hubConnection.InvokeAsync("DrawLine", 10, 10, 50, 50);

    // Verify in real SQL database
    var dbContext = app.Services.GetRequiredService<GameDbContext>();
    var session = await dbContext.Sessions
        .FirstOrDefaultAsync(s => s.Name == "TestRoom");

    Assert.That(session, Is.Not.Null);
}
  

Demo: Integration Testing

Aspire.Hosting.Testing in Action

  • Real DrawTogether integration tests
  • Full application spin-up per test
  • Parallel test execution
  • Automatic cleanup

Key Benefits:

  • No shared test database
  • No test data pollution
  • True end-to-end testing
  • Catches real integration issues

Reality Check

Let's talk about what doesn't work

What Aspire ISN'T (Yet)

The Dream ๐Ÿ˜‡

  • Development โœ…
  • Testing โœ…
  • Staging ๐Ÿค”
  • Production ๐Ÿ’€

The Reality ๐Ÿ˜ฌ

  • Dev-only orchestrator
  • No production story
  • Limited cloud support
  • Manual deployment config
"The deployment story is... virtually non-existent"

The Deployment "Story" ๐Ÿ“–

Target Status Reality
Azure (azd) โœ… Works Good integration, Container Apps
Kubernetes โš ๏ธ Community Aspirate/Aspire8 - not production ready
Docker Compose ๐Ÿ”ง Manual Generated, but needs manual config
AWS/GCP โŒ DIY No tooling, no roadmap

Bottom line: Great for dev, figure out prod yourself

Demo: Let's Try Deployment Anyway

Using the Aspire CLI


# Generate deployment artifacts
aspire generate --output-format docker-compose

# What we get vs what we need
  

Spoiler Alert:

  • Generates basic structure โœ“
  • Missing environment configs โœ—
  • No secrets management โœ—
  • Networking needs work โœ—

Practical Adoption

How to actually use this today

Can You Use .NET Aspire?

Prerequisites for Success:

1. Can you run dependencies locally?

  • Seeded databases (SQL, PostgreSQL, MongoDB)
  • Redis, RabbitMQ, storage emulators
  • Organizational commitment to maintain seed data

2. Is your code accessible?

  • Monorepo โ†’ Perfect fit
  • Multiple repos โ†’ Need Docker images
  • Can't access other teams' code โ†’ Challenging

3. Modern .NET stack?

  • Requires .NET 8+ for AppHost
  • Can orchestrate containerized legacy apps
  • IIS-dependent apps โ†’ Not compatible

If you meet these requirements: There's no reason NOT to use Aspire

Smart Adoption Strategy

Phase 1: Development (Now)

  • Add Aspire to existing apps
  • Improve developer onboarding
  • Standardize local environments

Phase 2: Testing (Now)

  • Replace mocked tests
  • Add end-to-end scenarios
  • Improve test coverage

Phase 3: Deployment (Wait)*

Key Takeaways

What to remember

Remember These Four Things

1. ๐Ÿš€ Dramatically Simplifies Local Dev

Git clone โ†’ F5 actually works

2. ๐Ÿงช Makes Real Integration Testing Feasible

Test with actual dependencies, not mocks

3. ๐Ÿ“Š Free Observability with OpenTelemetry

Dashboard, tracing, logs out of the box

Resources

Official Documentation

Sample Code

Community Tools

  • Aspirate (K8s deployment)
  • Azure Developer CLI (azd)

This Presentation

Thank You!

Questions?