Skip to content

adrianpy93/CloudNativeWorkshop

Repository files navigation

Cloud-Native Workshop - NDC Copenhagen 2025

A comprehensive .NET cloud-native workshop demonstrating modern distributed application patterns using .NET Aspire 13 and a modular monolith architecture.

Overview

This project showcases a complete e-learning platform built with cloud-native principles, featuring:

  • Modular Monolith Architecture - Domain-driven design with clear bounded contexts
  • .NET Aspire Orchestration - Streamlined local development with automatic infrastructure provisioning
  • PostgreSQL + Entity Framework Core - Primary relational database with code-first migrations
  • Distributed Caching - Redis for performance optimization
  • Message-Driven Communication - RabbitMQ for event-driven patterns
  • Cloud-Ready Design - Built for containerization and cloud deployment

Architecture

Application Structure

├── Dometrain.Aspire.AppHost       # Aspire orchestration host
├── Dometrain.Aspire.ServiceDefaults # Shared service configuration
└── Dometrain.Monolith.Api         # Main API (Modular Monolith)
    ├── Identity/                   # Authentication & authorization
    ├── Students/                   # Student management domain
    ├── Courses/                    # Course catalog domain
    ├── ShoppingCarts/              # Shopping cart domain
    ├── Orders/                     # Order processing domain
    ├── Enrollments/                # Course enrollment domain
    ├── Database/                   # EF Core DbContext, configurations, migrations
    ├── ErrorHandling/              # Centralized exception handling
    └── OpenApi/                    # Swagger configuration

Technology Stack

  • .NET 10 - Latest .NET runtime and SDK
  • .NET Aspire 13 - Cloud-native orchestration and tooling
  • ASP.NET Core Minimal APIs - Lightweight endpoint definitions
  • PostgreSQL 17 - Primary relational database (all domains)
  • Entity Framework Core - ORM with code-first migrations
  • Redis - Distributed caching layer
  • RabbitMQ - Message broker for async communication
  • FluentValidation - Request validation framework
  • OpenTelemetry - Observability (metrics, traces, logs)
  • Swashbuckle - OpenAPI/Swagger documentation

Infrastructure Components

All infrastructure is automatically managed by Aspire:

Component Purpose Port UI
PostgreSQL All transactional data 5433 -
Redis Caching - RedisInsight UI
RabbitMQ Message broker - Management Plugin UI

Prerequisites

Getting Started

1. Clone the Repository

git clone <repository-url>
cd cloud-native-workshop-ndccph-2025

2. Build the Solution

dotnet build CloudNativeWorkshop.sln

3. Run with Aspire

The recommended way to run the application is through the Aspire AppHost, which automatically starts all infrastructure:

dotnet run --project src/Dometrain.Aspire.AppHost

This will:

  • Start PostgreSQL container and create the dometrain database
  • Start Redis with RedisInsight
  • Launch RabbitMQ with Management Plugin
  • Start the main API
  • Apply EF Core migrations automatically
  • Open the Aspire Dashboard

4. Access the Application

First-Time Setup

On the first run, the application will:

  1. Create the PostgreSQL dometrain database
  2. Initialize all database tables
  3. Create a default admin user:
    • Email: admin@dometrain.com
    • ID: 005d25b1-bfc8-4391-b349-6cec00d1416c

Project Structure

Domain Organization

Each domain module follows a consistent subfolder structure:

{Domain}/
├── Models/
│   └── {Domain}.cs                    # Domain entity models
├── Interfaces/
│   ├── I{Domain}Repository.cs         # Repository interface
│   └── I{Domain}Service.cs            # Service interface
├── Services/
│   └── {Domain}Service.cs             # Business logic implementation
├── Repositories/
│   ├── {Domain}Repository.cs          # EF Core data access
│   └── Cached{Domain}Repository.cs    # Optional caching decorator
├── Api/
│   ├── {Domain}Endpoints.cs           # API endpoint handlers
│   └── {Domain}EndpointExtensions.cs  # Route registration
├── Mappers/
│   └── {Domain}Mapper.cs              # DTO-to-entity mapping
├── Validators/
│   └── {Domain}Validator.cs           # FluentValidation rules
├── Requests/
│   └── {Domain}Requests.cs            # Request DTOs
└── {MiscFiles}.cs                     # Config, extensions at root

Folders are only created when needed. Example - Students module:

Students/
├── Models/Student.cs
├── Interfaces/IStudentRepository.cs, IStudentService.cs
├── Services/StudentService.cs
├── Repositories/StudentRepository.cs
├── Api/StudentEndpoints.cs, StudentEndpointExtensions.cs
├── Mappers/StudentMapper.cs
├── Validators/StudentValidator.cs
└── Requests/StudentRequests.cs

Key Patterns

  • Minimal APIs - Lightweight endpoint definitions without controllers
  • Repository Pattern - Abstraction over data access
  • Decorator Pattern - Caching repositories wrap base repositories
  • Dependency Injection - Singleton lifetime for most services
  • Request/Response DTOs - Clear API contracts

Authentication & Authorization

JWT Authentication

The API uses JWT Bearer token authentication:

# Login to get token
POST /auth/login
{
  "email": "admin@dometrain.com",
  "password": "YourPassword"
}

Authorization Policies

  • Admin - Requires JWT with is_admin: true claim
  • ApiAdmin - Uses API key from configuration

API Testing

Use the included Insomnia collection for testing:

# Import the collection
insomnia-latest.yaml

The collection includes:

  • Authentication flows
  • Student management
  • Course operations
  • Shopping cart interactions
  • Order processing
  • Enrollment management

Development

Running Individual Components

# Run API directly (requires infrastructure running)
dotnet run --project src/Dometrain.Monolith.Api

# Run with Docker Compose (PostgreSQL only)
docker compose up db

Database Migrations

The application uses Entity Framework Core code-first migrations:

# Create a new migration
cd src/Dometrain.Monolith.Api
dotnet ef migrations add MigrationName --output-dir Database/Migrations

# Apply migrations manually (also runs on startup)
dotnet ef database update
  • Migrations are applied automatically on startup via context.Database.MigrateAsync()
  • EF Core configurations are in Database/Configurations/
  • No manual migration steps required for development

Adding a New Domain

  1. Create domain folder under Dometrain.Monolith.Api/ with subfolders
  2. Add Models/, Interfaces/, Services/, Repositories/, Api/ subfolders
  3. Implement entity models, repository, service, and endpoints
  4. Add EF Core configuration in Database/Configurations/
  5. Register DbSet in Database/DometrainDbContext.cs
  6. Register services and endpoints in Program.cs
  7. Add validation rules in Validators/
  8. Create EF Core migration for schema changes

Configuration

AppHost Settings

Located in src/Dometrain.Aspire.AppHost/appsettings.json:

  • Infrastructure connection strings (auto-generated)
  • Service discovery configuration
  • Telemetry settings

API Settings

Located in src/Dometrain.Monolith.Api/appsettings.json:

{
  "Identity": {
    "Key": "your-secret-key",
    "Issuer": "Dometrain",
    "Audience": "Dometrain.Api",
    "Lifetime": "08:00:00",
    "AdminApiKey": "your-admin-key"
  }
}

Observability

The application includes comprehensive observability via OpenTelemetry:

Metrics

  • Request counts and duration
  • Database query performance
  • Cache hit/miss ratios
  • Message processing metrics

Traces

  • Distributed tracing across services
  • Database query tracing
  • HTTP request tracing

Logs

  • Structured logging with correlation IDs
  • Integration with Aspire Dashboard

Monitoring Stack

# Prometheus metrics
http://localhost:9090

# Grafana dashboards
http://localhost:3000

# Aspire Dashboard (built-in)
# Opens automatically on startup

Troubleshooting

PostgreSQL Connection Issues

If the database fails to connect:

# Clean up existing containers and volumes
docker stop $(docker ps -q --filter name=main-db) 2>/dev/null || true
docker rm $(docker ps -aq --filter name=main-db) 2>/dev/null || true
docker volume rm $(docker volume ls -q --filter name=main-db) 2>/dev/null || true

# Restart Aspire
dotnet run --project src/Dometrain.Aspire.AppHost

Build Errors

If you encounter build errors:

# Clean and rebuild
dotnet clean
dotnet build --no-incremental

Port Conflicts

If ports are already in use, update them in AppHost.cs:

var postgres = builder.AddPostgres("main-db", port: 5433); // Change port here

Cloud Deployment

Container Support

Build the API as a container:

docker build -t dometrain-api -f src/Dometrain.Monolith.Api/Dockerfile .

Kubernetes Manifests

Pre-generated Kubernetes manifests are available in:

src/Dometrain.Aspire.AppHost/aspirate-output/

Deploy to Kubernetes:

kubectl apply -k src/Dometrain.Aspire.AppHost/aspirate-output/

Design Patterns Demonstrated

Architectural Patterns

  • Modular Monolith - Domain separation without microservices complexity
  • Repository Pattern - Data access abstraction
  • Decorator Pattern - Caching layer implementation
  • Dependency Injection - Loose coupling and testability

Cloud-Native Patterns

  • Health Checks - Application health monitoring
  • Configuration Management - External configuration
  • Service Discovery - Aspire-managed service resolution
  • Distributed Caching - Redis-based caching
  • Event-Driven Architecture - RabbitMQ messaging

Data Patterns

  • Repository Pattern - EF Core data access with IDbContextFactory
  • CQRS-lite - Read/write separation in repositories
  • Decorator Pattern - Caching repositories wrap base repositories

Performance Considerations

Caching Strategy

The application implements a two-tier caching approach:

  1. L1 Cache - In-memory application cache
  2. L2 Cache - Distributed Redis cache

Cached entities:

  • Courses (reduces database load)
  • Shopping carts (improves response time)

Database Optimization

  • Connection pooling - Managed by Npgsql
  • IDbContextFactory - Singleton repositories with short-lived DbContext per operation
  • Indexed lookups - On email, slug fields via EF Core configurations

Security

Authentication

  • JWT with symmetric key signing
  • Configurable token lifetime
  • Password hashing via ASP.NET Core Identity

Authorization

  • Claim-based authorization
  • API key authentication for admin operations
  • Role-based access control

Best Practices

  • Secrets in environment variables (production)
  • HTTPS enforcement (production)
  • Input validation via FluentValidation
  • SQL injection prevention via parameterized queries

License

This project is for educational purposes as part of the NDC Copenhagen 2025 Cloud-Native Workshop.

Additional Resources


Workshop: Cloud-Native Development with .NET Aspire Event: NDC Copenhagen 2025 Framework: .NET 10 | Aspire 13

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published