Skip to content

thirteeneight/templates

ย 
ย 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

30 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

.NET 9 Microservices Template

A comprehensive .NET 9 microservices template implementing Domain-Driven Design (DDD) patterns with modern cloud-native technologies. This template serves as a production-ready starting point for building distributed systems and is designed to become a dotnet template package in the future.

๐ŸŽฏ Template Vision

This project is being developed as a future dotnet template that developers can use to quickly scaffold robust microservices architectures. The template will provide:

  • Pre-configured microservices with DDD patterns
  • Production-ready infrastructure components
  • Modern observability and messaging patterns
  • Comprehensive testing strategies
  • Database schema management with Liquibase

๐Ÿ—๏ธ Architecture Overview

This template implements a microservices architecture using Domain-Driven Design principles with the following core patterns:

Service Structure Pattern

Each microservice follows a consistent layered architecture:

DomainName/
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ DomainName.Api/                  # REST/gRPC endpoints and controllers
โ”‚   โ”œโ”€โ”€ DomainName.AppHost/              # .NET Aspire orchestration host
โ”‚   โ”œโ”€โ”€ DomainName.BackOffice/           # Background jobs and event handlers
โ”‚   โ”œโ”€โ”€ DomainName.BackOffice.Orleans/   # Orleans grains (optional)
โ”‚   โ”œโ”€โ”€ DomainName.Contracts/            # Integration events and shared models
โ”‚   โ””โ”€โ”€ DomainName/                      # Core domain logic (commands, queries, entities)
โ”œโ”€โ”€ test/
โ”‚   โ””โ”€โ”€ DomainName.Tests/                # Integration and architecture tests
โ””โ”€โ”€ infra/
  โ””โ”€โ”€ DomainName.Database/             # Liquibase database migrations

Current Services

  • ๐Ÿงพ Billing Service - Manages cashiers, invoices, and payment processing
  • ๐Ÿ“Š Accounting Service - Handles ledgers, business day operations, and financial records
  • ๐Ÿ”ง Platform/Operations - Shared infrastructure, extensions, and service defaults

๐Ÿ”ง Technology Stack

Core Framework

  • .NET 9 - Latest framework with C# 13
  • ASP.NET Core - Web API and gRPC services
  • Minimal APIs - Lightweight HTTP APIs

Messaging & Communication

  • WolverineFx - CQRS/Event Sourcing framework
  • gRPC - High-performance inter-service communication
  • Apache Kafka - Distributed streaming platform
  • Protocol Buffers - Efficient serialization

Data & Persistence

  • PostgreSQL - Primary database engine
  • Dapper - Lightweight ORM with custom source generators
  • Liquibase - Database schema versioning and migration

Orchestration & Service Discovery

  • .NET Aspire - Cloud-native application orchestration
  • Microsoft Orleans - Virtual actor model (for stateful services)
  • Service Discovery - Automatic service registration and discovery

Observability & Monitoring

  • OpenTelemetry - Distributed tracing and metrics
  • Serilog - Structured logging
  • Health Checks - Service health monitoring
  • Orleans Dashboard - Real-time insights into Orleans grains

Testing

  • xUnit v3 - Unit and integration testing framework
  • Testcontainers - Integration testing with real dependencies
  • NetArchTest - Architecture compliance testing
  • NSubstitute - Mocking framework
  • Shouldly - Fluent assertions

Code Quality & Analysis

  • SonarAnalyzer - Static code analysis
  • FluentValidation - Input validation with automatic registration

Development Tools

  • Docker & Docker Compose - Containerization
  • Azure Storage - Cloud storage integration
  • HTTP Files - API testing and documentation

๐Ÿš€ Quick Start

Choose your preferred development approach:

โšก Quick Start - Aspire (Recommended)

The fastest way to get started is using .NET Aspire orchestration for a specific domain.

Prerequisites

๐Ÿงพ Billing Domain

# Clone and run Billing services
git clone <repository-url>
cd templates
cd Billing/src/Billing.AppHost
dotnet run

๐Ÿ“Š Accounting Domain

# Clone and run Accounting services
git clone <repository-url>
cd templates
cd Accounting/src/Accounting.AppHost
dotnet run

That's it! ๐ŸŽ‰ Aspire automatically:

  • โœ… Sets up databases with Liquibase
  • โœ… Starts all domain services (API, BackOffice, Orleans)
  • โœ… Configures service discovery
  • โœ… Provides observability dashboard

Access Points:

Port Assignment Pattern

The system uses a structured port allocation optimized for macOS compatibility:

Service Port Ranges

  • Billing: 8100-8119 (20 ports)
  • Accounting: 8120-8139 (20 ports)
  • Operations: 8140-8159 (20 ports)

Port Pattern Within Each Service

XX00: Aspire Resource Service (HTTP)
XX01: Main API (HTTP)
XX02: Main API (gRPC)
XX03: BackOffice (HTTP)
XX04: Orleans (HTTP)
XX10: Aspire Resource Service (HTTPS)
XX11: Main API (HTTPS)
XX13: BackOffice (HTTPS)
XX14: Orleans (HTTPS)
XX19: Documentation (last port of range)

Aspire Dashboard Ports

  • HTTP: Service base + 10,000 (e.g., 8100 โ†’ 18100)
  • HTTPS: Service base + 10,010 (e.g., 8100 โ†’ 18110)

Service Access Points


๐Ÿ”ง Manual Setup (Full Control)

For developers who want full control over the setup process.

Prerequisites

1. Clone and Build

git clone <repository-url>
cd templates
dotnet build Operations.slnx

2. Database Setup

Set up databases manually using Liquibase:

Important: The following commands assume your running PosgresSQL DB running on port 5432, has the username postgres and password password@, adjust if needed, by providing the CLI params --password or --username

# Billing Database
cd Billing/infra/Billing.Database/
liquibase update --defaults-file liquibase.setup.properties
liquibase update --defaults-file liquibase.servicebus.properties
liquibase update

# Accounting Database
cd ../../../Accounting/infra/Accounting.Database/
liquibase update --defaults-file liquibase.setup.properties
liquibase update --defaults-file liquibase.servicebus.properties
liquibase update

For detailed database instructions, see DATABASE_SETUP.md.

3. Run Services

Option A: Individual Services

# Terminal 1 - Billing API
dotnet run --project Billing/src/Billing.Api

# Terminal 2 - Billing BackOffice
dotnet run --project Billing/src/Billing.BackOffice

# Terminal 3 - Accounting API
dotnet run --project Accounting/src/Accounting.Api

# Terminal 4 - Accounting BackOffice
dotnet run --project Accounting/src/Accounting.BackOffice

Option B: Docker Compose

docker compose up --build

Option C: Individual Docker Builds

# Build individual service images
docker build -t billing-api -f Billing/src/Billing.Api/Dockerfile .
docker build -t billing-backoffice -f Billing/src/Billing.BackOffice/Dockerfile .
docker build -t accounting-api -f Accounting/src/Accounting.Api/Dockerfile .
docker build -t accounting-backoffice -f Accounting/src/Accounting.BackOffice/Dockerfile .

# Run individual containers
docker run -p 8101:8080 billing-api
docker run -p 8121:8080 accounting-api

4. Verify Manual Setup


๐Ÿงช Quick Test

Test the APIs with the included HTTP files:

# Install REST Client extension in VS Code, then open:
# .http/Billing.Api.http
# .http/Accounting.Api.http

Or use curl:

# Create a cashier
curl -X POST http://localhost:8101/cashiers \
  -H "Content-Type: application/json" \
  -d '{"name": "Test Cashier", "currencyCode": "USD"}'

# Create a ledger
curl -X POST http://localhost:8121/ledgers \
  -H "Content-Type: application/json" \
  -d '{"name": "Test Ledger", "type": "Asset"}'

๐Ÿ“‹ Development Commands

Building and Testing

# Build entire solution
dotnet build Operations.slnx

# Run all tests
dotnet test

# Run specific service tests
dotnet test Billing/test/Billing.Tests
dotnet test Accounting/test/Accounting.Tests

Docker Commands

# Build all service images
docker build -t billing-api -f Billing/src/Billing.Api/Dockerfile .
docker build -t billing-backoffice -f Billing/src/Billing.BackOffice/Dockerfile .
docker build -t accounting-api -f Accounting/src/Accounting.Api/Dockerfile .
docker build -t accounting-backoffice -f Accounting/src/Accounting.BackOffice/Dockerfile .

# Run with Docker Compose (full stack)
docker-compose up --build

# Run individual containers
docker run -p 8101:8080 --name billing-api billing-api
docker run -p 8103:8080 --name billing-backoffice billing-backoffice
docker run -p 8121:8080 --name accounting-api accounting-api
docker run -p 8123:8080 --name accounting-backoffice accounting-backoffice

Database Management

# Check migration status
liquibase status

# View migration history
liquibase history

# Rollback last migration
liquibase rollback-count 1

๐Ÿงฉ Key Features

๐Ÿ”จ Custom Source Generators

The template includes powerful source generators for reducing boilerplate:

DbCommand Source Generator

Automatically generates Dapper command handlers and parameter mappers:

[DbCommand(sp: "create_cashier", nonQuery: true)]
public partial record CreateCashierCommand(string Name, decimal Balance) : ICommand<int>;

// Generates: DB access methods that executes the stored procedure create_cashier and return the affected records (nonQuery)

For detailed documentation, see Platform/src/Operations.Extensions.SourceGenerators/README.md.

๐Ÿ”„ CQRS with WolverineFx

Command and Query separation with automatic handler discovery:

// Command
public record CreateLedgerCommand(string Name, LedgerType Type) : ICommand<Guid>;

// Query  
public record GetLedgerQuery(Guid Id) : IQuery<Ledger>;

// Handlers auto-discovered and registered
public class CreateLedgerHandler
{
    public async Task<Guid> Handle(CreateLedgerCommand command, CancellationToken ct)
    {
        // Implementation
    }
}

๐Ÿ“ก gRPC Service Communication

Type-safe inter-service communication with Protocol Buffers:

service Ledgers {
  rpc GetLedger(GetLedgerRequest) returns (GetLedgerResponse);
  rpc CreateLedger(CreateLedgerRequest) returns (CreateLedgerResponse);
}

๐Ÿ” Comprehensive Testing

Multiple testing layers with real infrastructure:

[Fact]
public async Task CreateCashier_ShouldReturnSuccess()
{
    // Integration test with Testcontainers PostgreSQL
    await using var app = new BillingApiWebAppFactory();
    var client = app.CreateClient();
    
    var response = await client.PostAsJsonAsync("/cashiers", new CreateCashierRequest(...));
    
    response.StatusCode.ShouldBe(HttpStatusCode.Created);
}

๐Ÿ“Š Built-in Observability

Production-ready monitoring and tracing:

  • Distributed Tracing - OpenTelemetry with automatic instrumentation
  • Structured Logging - Serilog with correlation IDs
  • Health Checks - Endpoint monitoring with custom checks
  • Metrics - Custom metrics with OpenTelemetry

๐Ÿ“ Project Structure

/
โ”œโ”€โ”€ ๐Ÿ“‹ Operations.slnx              # Solution file with organized folders
โ”œโ”€โ”€ ๐Ÿณ compose.yaml                 # Docker Compose services
โ”œโ”€โ”€ ๐Ÿ“ฆ Directory.Packages.props     # Centralized NuGet package management
โ”œโ”€โ”€ ๐Ÿ—๏ธ Directory.Build.props        # Shared MSBuild properties
โ”‚
โ”œโ”€โ”€ ๐Ÿงพ Billing/                     # Billing microservice
โ”‚   โ”œโ”€โ”€ docs/                       # Project documentation, including code docs
โ”‚   โ”œโ”€โ”€ src/                        # Source code
โ”‚   โ”œโ”€โ”€ test/                       # Tests
โ”‚   โ”œโ”€โ”€ web/                        # UI project
โ”‚   โ””โ”€โ”€ infra/                      # Infrastructure (database)
โ”‚
โ”œโ”€โ”€ ๐Ÿ“Š Accounting/                  # Accounting microservice
โ”‚   โ”œโ”€โ”€ src/                        # Source code  
โ”‚   โ”œโ”€โ”€ test/                       # Tests
โ”‚   โ””โ”€โ”€ infra/                      # Infrastructure (database)
โ”‚
โ””โ”€โ”€ ๐Ÿ”ง Platform/                    # Shared platform components
    โ”œโ”€โ”€ src/
    โ”‚   โ”œโ”€โ”€ Operations.Extensions/           # Custom extensions and utilities
    โ”‚   โ”œโ”€โ”€ Operations.Extensions.Abstractions/  # Interfaces and attributes
    โ”‚   โ”œโ”€โ”€ Operations.Extensions.SourceGenerators/  # Code generators
    โ”‚   โ”œโ”€โ”€ Operations.ServiceDefaults/      # Shared service configuration
    โ”‚   โ”œโ”€โ”€ Operations.ServiceDefaults.Api/  # API-specific defaults
    โ”‚   โ””โ”€โ”€ Operations.AppHost/              # Aspire orchestration
    โ””โ”€โ”€ test/                               # Platform tests

๐Ÿ”ง Configuration

Global Settings

The template uses centralized configuration management:

  • Directory.Build.props - Shared MSBuild properties and package references
  • Directory.Packages.props - Centralized package version management
  • Operations.ruleset - Code analysis rules
  • .editorconfig - Code style enforcement

Environment Configuration

Services support multiple configuration sources:

  • appsettings.json - Base configuration
  • appsettings.Development.json - Development overrides
  • Environment Variables - Container/cloud deployment
  • User Secrets - Local development secrets

Source Generator Configuration

Configure source generators globally via MSBuild properties:

<PropertyGroup>
  <!-- If using postgres -->
  <DbCommandDefaultParamCase>SnakeCase</DbCommandDefaultParamCase>
</PropertyGroup>

๐Ÿงช Testing Strategy

Test Categories

  1. Unit Tests - Fast, isolated component tests
  2. Integration Tests - Service-level tests with real dependencies
  3. Architecture Tests - Enforce architectural constraints

Test Infrastructure

  • Testcontainers - Real PostgreSQL instances for integration tests
  • WebApplicationFactory - In-memory test servers
  • Custom Test Fixtures - Shared test infrastructure
  • Test Data Builders - Consistent test data creation

๐Ÿš€ Deployment

Container Support

All services include optimized Dockerfiles:

FROM mcr.microsoft.com/dotnet/aspnet:9.0-alpine AS base
# Multi-stage builds for optimal image size

Database Migrations

Liquibase handles database schema evolution:

  • Version Control - All schema changes tracked in Git
  • Rollback Support - Safe rollback to previous versions
  • Environment Promotion - Consistent schema across environments

๐Ÿ”ฎ Future Template Features

When this becomes a dotnet template, it will support:

Template Parameters

dotnet new microservice-template \
  --name "Billing" \
  --database "pgsql" \
  --messaging "kafka" \

Customization Options

  • Service Selection - Choose which services to include
  • Technology Choices - Alternative databases, messaging systems
  • Authentication - JWT, OAuth2, Azure AD integration

๐Ÿค Contributing

This template is designed to incorporate best practices and patterns. Contributions are welcome for:

  • New microservice patterns
  • Additional source generators
  • Enhanced testing strategies
  • Cloud deployment templates
  • Documentation improvements

๐Ÿ“š Additional Resources

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • C# 73.3%
  • TypeScript 14.2%
  • Svelte 8.9%
  • Dockerfile 2.2%
  • JavaScript 0.6%
  • CSS 0.4%
  • Other 0.4%