Get up and running in three simple steps:
- Install Prerequisites - Set up your development environment
- Run the Application - Start the AppHost with .NET Aspire
- Start Developing - Access Swagger UI and begin building features
Prerequisites​
Windows Development Setup​
Step 1: Install WSL (Windows Subsystem for Linux)​
Open PowerShell as Administrator and run:
wsl --install
Important: Restart your computer after installation.
Step 2: Install Required Development Tools​
Run the following command in PowerShell (as Administrator):
@(
"Microsoft.DotNet.SDK.9",
"Git.Git",
"Docker.DockerDesktop",
"OpenJS.NodeJS",
"GitHub.cli"
) | ForEach-Object { winget install --accept-package-agreements --accept-source-agreements --id $_ }
This will use Winget to install:
- .NET 10 SDK - Runtime and development tools
- Git - Version control
- Docker Desktop - Container runtime
- Node.js - JavaScript runtime for tooling
- GitHub CLI - GitHub integration
Step 3: Verify Installation​
dotnet --version
git --version
docker --version
node --version
gh --version
Recommended Optional Tools​
@(
"Microsoft.VisualStudioCode",
"JetBrains.Rider",
"Postman.Postman",
) | ForEach-Object { winget install --accept-package-agreements --accept-source-agreements --id $_ }
Port Mappings​
Development Environment​
| Service | HTTP | HTTPS | Purpose |
|---|---|---|---|
| AppHost | - | https://localhost:17298 | .NET Aspire Dashboard |
| Web (Blazor) | http://localhost:8082 | https://localhost:8083 | Frontend Application |
| API | http://localhost:8080/api | https://localhost:8081/api | REST API Backend |
| Gateway | http://localhost:8084/gw/health | https://localhost:8085/gw/health | YARP Reverse Proxy |
Port Configuration Precedence​
ASP.NET Core determines port mappings in the following order (highest to lowest priority):
Command-line arguments
dotnet run --urls "http://localhost:5000"**Code-level configuration in Program.cs **
builder.WebHost.ConfigureKestrel(options => { ... })Launch Settings / Environment Variables
// launchSettings.json "environmentVariables": { "ASPNETCORE_URLS": "https://localhost:8081" }App Settings Files
// appsettings.json "Kestrel": { "Endpoints": { ... } }
Running the Application​
cd C:\Development\Development-Projects\saas-factory-labs\Code\AppBlueprint\AppBlueprint.AppHost
dotnet run
The .NET Aspire dashboard will open automatically at https://localhost:17298 and display the following services: Web, API, Gateway
Individual Project Development​
# Run API only
cd AppBlueprint.ApiService
dotnet watch
# Run Web only
cd AppBlueprint.Web
dotnet watch
# Run with hot reload
dotnet watch
API Documentation​
Swagger UI​
Access the interactive API documentation at:
URL: https://localhost:8081/index.html

OpenAPI Specification​
Download the raw OpenAPI/Swagger JSON:
URL: https://localhost:8081/swagger/v1/swagger.json

Generating API Clients​
The project uses Kiota to generate strongly-typed API clients:
# Regenerate API client SDK
cd Shared-Modules\AppBlueprint.Api.Client.Sdk
dotnet build
Database Management​
Entity Framework Core Migrations​
All commands should be executed from the AppBlueprint.Infrastructure project directory since the DbContext resides there.
cd Code\AppBlueprint\Shared-Modules\AppBlueprint.Infrastructure
Common EF Core Commands​
View Database Context Information​
dotnet ef dbcontext info --context "ApplicationDBContext"
Create a New Migration​
dotnet ef migrations add <name> --context ApplicationDBContext
Apply Migrations to Database​
dotnet ef database update --context ApplicationDBContext
Remove Last Migration​
dotnet ef migrations remove --context ApplicationDBContext
Generate SQL Script​
dotnet ef migrations script --context ApplicationDBContext --output migration.sql
Database Connection Strings​
Connection strings are configured via environment variables or appsettings.json:
DATABASE_CONNECTION_STRING="Host=localhost;Database=appblueprint;Username=postgres;Password=your_password"
Key Configuration Files​
Directory.Packages.props​
Central package management for all C# projects. Packages are referenced in each C# project's .csproj file without a version, which is sourced from the Directory.Packages.props file:
<PackageReference Include="Microsoft.EntityFrameworkCore" />
Location: Code/AppBlueprint/Directory.Packages.props
Directory.Build.props​
Defines common MSBuild properties for all projects in the solution.
Location: Code/AppBlueprint/Directory.Build.props
<!-- This file is used to define the common properties for all projects in the solution -->
<Project>
<PropertyGroup>
<Targetframework>net9.0</Targetframework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AnalysisLevel>latest</AnalysisLevel>
<AnalysisMode>All</AnalysisMode>
</PropertyGroup>
</Project>
NuGet.Config​
Central NuGet package source configuration, including GitHub Packages integration.
Location: Code/AppBlueprint/NuGet.Config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
<add key="saas-factory-labs-github" value="https://nuget.pkg.github.com/saas-factory-labs/index.json" />
</packageSources>
</configuration>
Package Versioning (NuGet, Docker)​
Automatic Versioning with GitVersion​
Set this property in the .csproj file of a C# project to enable automatic versioning using the GitVersion tool:
<PropertyGroup>
<Version>$(GITVERSION_SemVer)</Version>
</PropertyGroup>
Docker Configuration​
Building Docker Images​
Build a Docker image from the correct build context:
cd Code/AppBlueprint
docker build -f AppBlueprint.Web/Dockerfile . -t appblueprint-web:dev
Important: The build context must be set to
Code/AppBlueprintdirectory to ensure access toDirectory.Packages.props,NuGet.Config, and dependent projects.
GitHub Container Registry Login​
To pull/push images from GitHub Container Registry (ghcr.io) on a VM or Coolify:
docker login ghcr.io -u saas-factory-labs
# Enter your GitHub Personal Access Token (PAT) when prompted
Development Tools​
Running GitHub Actions Locally with Act​
Act allows you to test GitHub Actions workflows locally using Docker.
Install Act​
winget install nektos.act
Run All Workflows​
act -P ubuntu-latest=ghcr.io/catthehacker/ubuntu:act-latest
Run Specific Workflow​
act -P ubuntu-latest=ghcr.io/catthehacker/ubuntu:act-latest -j publish-packages
Upgrading .NET Aspire​
To upgrade to the latest .NET Aspire version:
Install Upgrade Assistant​
dotnet tool install -g upgrade-assistant
Run Upgrade​
upgrade-assistant upgrade
Reference: Microsoft .NET Aspire Upgrade Guide
Best Practices​
Null Reference Validation​
Follow these patterns for null checking in the codebase:
// ✅ Preferred: Throw if null with inline check
var user = await _dbContext.GetUser(userId)
?? throw new ArgumentNullException(nameof(userId));
// ✅ Pattern: Explicit null check with is null
if (user is null)
{
throw new ArgumentNullException(nameof(user));
}
// ✅ Pattern: Explicit not null check
if (user is not null)
{
// Process user
}
Recommended Packages​
FluentRegex​
Create human-readable regular expressions:
// Instead of: @"^\d{3}-\d{2}-\d{4}$"
var pattern = Pattern.With
.StartOfString()
.Digit().Repeat.Exactly(3)
.Literal("-")
.Digit().Repeat.Exactly(2)
.Literal("-")
.Digit().Repeat.Exactly(4)
.EndOfString()
.ToString();
Repository: https://github.com/bcwood/FluentRegex
Troubleshooting​
Common Issues​
Port Already in Use​
# Find process using port 8081
netstat -ano | findstr :8081
# Kill the process (replace <PID> with actual process ID)
taskkill /PID <PID> /F
Database Connection Errors​
- Verify PostgreSQL is running in Docker
- Check connection string environment variables
- Ensure migrations are applied:
dotnet ef database update --context ApplicationDBContext
Additional Resources​
Getting Help​
- GitHub Issues: Report a bug or request a feature
- GitHub Discussions: Ask questions and share ideas