Momentum.Template 0.0.1-pre.13

This is a prerelease version of Momentum.Template.
There is a newer version of this package available.
See the version list below for details.
dotnet new install Momentum.Template::0.0.1-pre.13
                    
This package contains a .NET Template Package you can call from the shell/command line.

Momentum .NET

NuGet NuGet Preview Downloads License

Welcome to Momentum - a comprehensive .NET 9 template system that generates complete, production-ready microservices solutions. Whether you're building APIs, event-driven backends, or stateful processing systems, Momentum provides the architecture, patterns, and infrastructure you need to get productive immediately.

Quick Start (2 Minutes)

Get a complete microservices solution running in under 2 minutes:

1. Install the Template

# Install from NuGet (recommended)
dotnet new install Momentum.Template

2. Generate Your Solution

# Create a complete microservices solution
dotnet new mmt -n OrderService --allow-scripts yes
cd OrderService

3. Start Everything with Aspire

# Launch the complete application stack
dotnet run --project src/OrderService.AppHost

# Access the Aspire Dashboard: https://localhost:18110
# API endpoints: https://localhost:8101
# Documentation: http://localhost:8119

That's it! You now have a running microservices solution with:

  • ✅ REST and gRPC APIs with sample endpoints
  • ✅ Background event processing with Wolverine
  • ✅ PostgreSQL database with migrations
  • ✅ Apache Kafka messaging
  • ✅ Comprehensive observability
  • ✅ Live documentation
  • ✅ Sample business domain (Cashiers/Invoices)

Technology Stack

Momentum is built on modern, production-proven technologies:

  • 🎯 .NET 9: Latest framework with performance optimizations
  • 🏗️ .NET Aspire: Local development orchestration and observability
  • 🎭 Orleans: Stateful actor-based processing for complex workflows
  • ⚡ Wolverine: CQRS/MediatR pattern with message handling
  • 🚀 gRPC + REST: Dual API protocols for performance and compatibility
  • 📡 Apache Kafka: Event streaming and reliable messaging
  • 🗄️ PostgreSQL: Robust relational database with JSON support
  • 🔄 Liquibase: Version-controlled database migrations
  • 📊 OpenTelemetry: Distributed tracing and observability
  • 🧪 Testcontainers: Real infrastructure for integration testing

Template System Overview

Momentum Template (dotnet new mmt) generates customized microservices solutions that mirror real-world business operations. The template leverages Wolverine for CQRS patterns and supports multiple architectures from simple APIs to complex event-driven systems with Orleans actors.

Core Architecture Principles

  • 🎯 Real-World Mirroring: Code structure corresponds to business operations and processes
  • 🚫 No Smart Objects: Entities are data records, not self-modifying objects
  • 🏢 Front/Back Office: Synchronous APIs vs Asynchronous processing
  • 📡 Event-Driven: Integration events via Kafka with Wolverine message handling
  • 🧪 Testing First: Comprehensive testing with real infrastructure

Prerequisites

Before getting started, ensure you have:

  • .NET 9 SDK - Download here
  • IDE: Visual Studio, VS Code with C# Dev Kit, or JetBrains Rider
  • Docker Desktop - Required for databases, Kafka, and local development

Template Configuration Options

The template supports extensive customization through parameters. Here are the most common configurations:

Simple API Service

# Generate API-only service
dotnet new mmt -n PaymentService --api --back-office false --orleans false --docs false

Orleans Processing Engine

# Generate stateful processing service
dotnet new mmt -n WorkflowEngine --orleans --api false --port 9000

Full Stack Solution

# Generate complete solution with custom settings
dotnet new mmt -n EcommercePlatform --org "Acme Corp" --port 7000

Minimal Setup

# Clean slate without sample code
dotnet new mmt -n CleanService --no-sample

Available Template Parameters

The template offers comprehensive configuration options:

Core Components:

  • --api: REST/gRPC API project (default: true)
  • --back-office: Background processing project (default: true)
  • --aspire: .NET Aspire orchestration project (default: true)
  • --docs: VitePress documentation project (default: true)
  • --orleans: Orleans stateful processing project (default: false)

Infrastructure:

  • --kafka: Apache Kafka messaging (default: true)
  • --db: Database setup (default, npgsql, liquibase)
  • --port: Base port number (default: 8100)

Customization:

  • --org: Organization name for copyright headers, github, etc
  • --no-sample: Exclude sample code (default: false, use --no-sample to skip)
  • --project-only: Generate only projects without solution files
  • --libs: Include Momentum libraries as project references
  • --lib-name: Custom prefix to replace "Momentum" in library names

[!NOTE] For complete parameter documentation and all available combinations, see the template.json file and the Template Options Guide for detailed use cases and examples.

Understanding the Generated Solution

The template generates a production-ready solution with clear separation of concerns:

Project Structure

OrderService/
├── src/
│   ├── OrderService.Api/              # REST & gRPC endpoints
│   ├── OrderService.BackOffice/        # Event processing
│   ├── OrderService.BackOffice.Orleans/ # Stateful processing (if enabled)
│   ├── OrderService.AppHost/           # Aspire orchestration
│   ├── OrderService/                   # Core domain logic
│   └── OrderService.Contracts/         # Integration events
├── infra/
│   └── OrderService.Database/          # Liquibase migrations
├── tests/
│   └── OrderService.Tests/             # Comprehensive testing
├── docs/                               # VitePress documentation
└── compose.yml                         # Docker Compose for services

Business Domain Organization

Generated code follows Domain-Driven Design principles with Wolverine CQRS patterns:

src/OrderService/
├── Cashiers/                  # Sample business domain
│   ├── Commands/              # Business actions (Wolverine handlers)
│   ├── Queries/               # Information retrieval (Wolverine handlers)
│   ├── Data/                  # Database operations
│   └── Contracts/             # Domain events
└── Invoices/                  # Another sample domain
    ├── Commands/              # Commands with validation
    ├── Queries/               # Queries for data retrieval
    ├── Data/                  # Database access layer
    └── Contracts/             # Integration events

Port Configuration

Services use a base port system (default: 8100):

Service HTTP HTTPS gRPC Purpose
Aspire Dashboard 18100 18110 - Development dashboard
API 8101 8111 8102 REST & gRPC endpoints
BackOffice 8103 8113 - Background processing
Orleans 8104 8114 - Stateful processing
Documentation 8119 - - VitePress docs
PostgreSQL 54320 - - Database
Kafka 59092 - - Message broker

Customize the base port with --port 9000 to use 9100, 9101, etc.

Individual Libraries Approach

For existing projects or custom architectures, you can use Momentum Libraries individually. All these capabilities can also be configured through the template system with selective feature inclusion:

📚 Note: The template system (dotnet new mmt) allows you to configure which libraries and features to include, so you can generate solutions with only the specific Momentum capabilities you need.

Build a simple API service using individual Momentum Libraries when you need to add capabilities to existing projects:

1. Create New Project

# Create a new ASP.NET Core API project
dotnet new webapi -n OrderService
cd OrderService

# Add the essential Momentum packages
dotnet add package Momentum.ServiceDefaults --version 0.0.1
dotnet add package Momentum.Extensions --version 0.0.1

Library Integration Results

Congratulations! You've added powerful capabilities to your application:

  • ✅ Structured error handling with Result types
  • ✅ Built-in health checks and metrics
  • ✅ OpenTelemetry observability
  • ✅ Structured logging with Serilog
  • ✅ Production-ready service defaults

Individual Libraries Overview

When using libraries individually (rather than the template), each library serves a specific purpose and can be used independently:

Momentum.Extensions - Core Foundation

Essential utilities and patterns for any .NET application.

dotnet add package Momentum.Extensions

Key Features:

  • ResultOfT Types: Elegant error handling without exceptions
  • Validation Integration: FluentValidation helpers and extensions
  • Data Access: Enhanced Dapper extensions and LINQ2DB support
  • Messaging Abstractions: Base interfaces for CQRS and event-driven design with Wolverine integration

Use When: You want robust error handling and core utilities in any .NET project.

Momentum.ServiceDefaults - Production Readiness

Complete service configuration for Aspire-based applications.

dotnet add package Momentum.ServiceDefaults

Key Features:

  • Aspire Integration: Full .NET Aspire service defaults implementation
  • Observability Stack: OpenTelemetry + Serilog for monitoring
  • Health Checks: Built-in application health monitoring
  • Resilience: HTTP client resilience patterns
  • Service Discovery: Automatic service resolution

Use When: Building microservices, APIs, or any distributed application that needs production-ready configuration.

Momentum.ServiceDefaults.Api - API Enhancements

Additional features specifically for REST and gRPC APIs.

dotnet add package Momentum.ServiceDefaults.Api

Key Features:

  • OpenAPI: Enhanced Swagger documentation with XML docs
  • gRPC Support: Service registration and health checks
  • Route Conventions: Kebab-case URL transformations
  • Response Types: Automatic response type generation

Use When: Building REST APIs or gRPC services that need enhanced documentation and conventions.

Momentum.Extensions.SourceGenerators - Code Generation

Compile-time code generation for common patterns.

dotnet add package Momentum.Extensions.SourceGenerators

Key Features:

  • DbCommand Generation: Type-safe database command handlers
  • Zero Runtime Overhead: All generation happens at compile time
  • IDE Integration: Generated code appears in IntelliSense
  • Customizable: Configure generation through attributes and MSBuild properties

Use When: You want to eliminate boilerplate code and ensure type safety for database operations.

Momentum.Extensions.Messaging.Kafka - Event-Driven Architecture

Kafka integration with CloudEvents standard support.

dotnet add package Momentum.Extensions.Messaging.Kafka

Key Features:

  • CloudEvents: Standards-compliant event serialization
  • Kafka Integration: Producer and consumer patterns
  • Partition Key Support: Automatic partitioning strategies
  • Observability: Built-in metrics and tracing

Use When: Building event-driven microservices that need reliable messaging.

Advanced Library Integration Example

When using individual libraries, here's how to build a more complete application that demonstrates library integration:

1. Setup Project

# Create new project
dotnet new webapi -n EcommerceService
cd EcommerceService

# Add comprehensive Momentum packages
dotnet add package Momentum.ServiceDefaults
dotnet add package Momentum.Extensions
dotnet add package Momentum.Extensions.SourceGenerators
dotnet add package Npgsql  # For PostgreSQL
dotnet add package FluentValidation.DependencyInjectionExtensions

2. Database Models and Commands

Create Domain/Orders/Order.cs:

namespace EcommerceService.Domain.Orders;

// Database entity
public class OrderEntity
{
    public Guid Id { get; set; }
    public string CustomerName { get; set; } = string.Empty;
    public string ProductName { get; set; } = string.Empty;
    public decimal Amount { get; set; }
    public DateTime CreatedAt { get; set; }
    public DateTime UpdatedAt { get; set; }
}

// Public model
public record Order(
    Guid Id,
    string CustomerName,
    string ProductName,
    decimal Amount,
    DateTime CreatedAt
);

// Extension for conversion
public static class OrderExtensions
{
    public static Order ToModel(this OrderEntity entity) => new(
        entity.Id,
        entity.CustomerName,
        entity.ProductName,
        entity.Amount,
        entity.CreatedAt
    );
}

3. Commands with Validation

Create Domain/Orders/Commands/CreateOrder.cs:

using FluentValidation;
using Momentum.Extensions;

namespace EcommerceService.Domain.Orders.Commands;

public record CreateOrderCommand(
    string CustomerName,
    string ProductName,
    decimal Amount
) : ICommand<Result<Order>>;

public class CreateOrderValidator : AbstractValidator<CreateOrderCommand>
{
    public CreateOrderValidator()
    {
        RuleFor(x => x.CustomerName)
            .NotEmpty()
            .WithMessage("Customer name is required")
            .MinimumLength(2)
            .WithMessage("Customer name must be at least 2 characters")
            .MaximumLength(100)
            .WithMessage("Customer name cannot exceed 100 characters");

        RuleFor(x => x.ProductName)
            .NotEmpty()
            .WithMessage("Product name is required")
            .MaximumLength(200)
            .WithMessage("Product name cannot exceed 200 characters");

        RuleFor(x => x.Amount)
            .GreaterThan(0)
            .WithMessage("Amount must be greater than zero")
            .LessThanOrEqualTo(1000000)
            .WithMessage("Amount cannot exceed $1,000,000");
    }
}

4. Database Commands with Source Generation

Create Domain/Orders/Data/OrderDbCommands.cs:

using Dapper;
using Momentum.Extensions.Abstractions.Dapper;
using System.Data;

namespace EcommerceService.Domain.Orders.Data;

public static class CreateOrderDbCommandHandler
{
    [DbCommand]
    public record DbCommand(OrderEntity Order) : ICommand<OrderEntity>;

    public static async Task<OrderEntity> Handle(
        DbCommand command,
        IDbConnection db,
        CancellationToken cancellationToken)
    {
        const string sql = """
            INSERT INTO orders (id, customer_name, product_name, amount, created_at, updated_at)
            VALUES (@Id, @CustomerName, @ProductName, @Amount, @CreatedAt, @UpdatedAt)
            RETURNING *;
            """;

        var order = command.Order;
        return await db.QuerySingleAsync<OrderEntity>(sql, new
        {
            order.Id,
            order.CustomerName,
            order.ProductName,
            order.Amount,
            order.CreatedAt,
            order.UpdatedAt
        });
    }
}

public static class GetOrderDbCommandHandler
{
    [DbCommand]
    public record DbCommand(Guid OrderId) : ICommand<OrderEntity?>;

    public static async Task<OrderEntity?> Handle(
        DbCommand command,
        IDbConnection db,
        CancellationToken cancellationToken)
    {
        const string sql = "SELECT * FROM orders WHERE id = @OrderId";
        return await db.QuerySingleOrDefaultAsync<OrderEntity>(sql, new { command.OrderId });
    }
}

5. Business Logic Handler

Create Domain/Orders/Commands/CreateOrderHandler.cs:

using EcommerceService.Domain.Orders.Data;
using FluentValidation;
using Momentum.Extensions;

namespace EcommerceService.Domain.Orders.Commands;

public static class CreateOrderCommandHandler
{
    public static async Task<Result<Order>> Handle(
        CreateOrderCommand command,
        IValidator<CreateOrderCommand> validator,
        IMessageBus messageBus,
        CancellationToken cancellationToken)
    {
        // Validate input
        var validationResult = await validator.ValidateAsync(command, cancellationToken);
        if (!validationResult.IsValid)
        {
            return Result<Order>.Failure(validationResult.Errors);
        }

        // Create database entity
        var orderEntity = new OrderEntity
        {
            Id = Guid.CreateVersion7(),
            CustomerName = command.CustomerName,
            ProductName = command.ProductName,
            Amount = command.Amount,
            CreatedAt = DateTime.UtcNow,
            UpdatedAt = DateTime.UtcNow
        };

        // Save to database using generated command
        var dbCommand = new CreateOrderDbCommandHandler.DbCommand(orderEntity);
        var savedOrder = await messageBus.InvokeAsync(dbCommand, cancellationToken);

        return Result<Order>.Success(savedOrder.ToModel());
    }
}

6. API Configuration

Update Program.cs:

using EcommerceService.Domain.Orders.Commands;
using FluentValidation;
using Momentum.Extensions;
using Npgsql;
using System.Data;

var builder = WebApplication.CreateBuilder(args);

// Add Momentum service defaults
builder.AddServiceDefaults();

// Add database connection
builder.Services.AddScoped<IDbConnection>(provider =>
{
    var connectionString = builder.Configuration.GetConnectionString("DefaultConnection")
        ?? "Host=localhost;Database=ecommerce;Username=postgres;Password=password";
    return new NpgsqlConnection(connectionString);
});

// Add FluentValidation
builder.Services.AddValidatorsFromAssemblyContaining<CreateOrderValidator>();

// Add custom services
builder.Services.AddScoped<IOrderService, OrderService>();

var app = builder.Build();

// Configure pipeline
app.MapDefaultEndpoints();

// Add API endpoints
app.MapPost("/orders", async (
    CreateOrderCommand command,
    IValidator<CreateOrderCommand> validator,
    IMessageBus messageBus,
    CancellationToken cancellationToken) =>
{
    var result = await CreateOrderCommandHandler.Handle(command, validator, messageBus, cancellationToken);

    return result.IsSuccess
        ? Results.Created($"/orders/{result.Value.Id}", result.Value)
        : Results.BadRequest(result.Errors.Select(e => new { e.PropertyName, e.ErrorMessage }));
});

app.MapGet("/orders/{id:guid}", async (
    Guid id,
    IMessageBus messageBus,
    CancellationToken cancellationToken) =>
{
    var dbCommand = new GetOrderDbCommandHandler.DbCommand(id);
    var orderEntity = await messageBus.InvokeAsync(dbCommand, cancellationToken);

    return orderEntity is not null
        ? Results.Ok(orderEntity.ToModel())
        : Results.NotFound();
});

await app.RunAsync();

7. Database Setup

Create a simple migration script setup.sql:

-- Create orders table
CREATE TABLE IF NOT EXISTS orders (
    id UUID PRIMARY KEY,
    customer_name VARCHAR(100) NOT NULL,
    product_name VARCHAR(200) NOT NULL,
    amount DECIMAL(10,2) NOT NULL,
    created_at TIMESTAMP WITH TIME ZONE NOT NULL,
    updated_at TIMESTAMP WITH TIME ZONE NOT NULL
);

-- Create index for performance
CREATE INDEX IF NOT EXISTS idx_orders_created_at ON orders(created_at);

8. Configuration

Create appsettings.Development.json:

{
    "ConnectionStrings": {
        "DefaultConnection": "Host=localhost;Database=ecommerce;Username=postgres;Password=password"
    },
    "Logging": {
        "LogLevel": {
            "Default": "Information",
            "Microsoft.AspNetCore": "Warning"
        }
    }
}

9. Run and Test

# Start PostgreSQL (using Docker)
docker run --name postgres-ecommerce -e POSTGRES_PASSWORD=password -e POSTGRES_DB=ecommerce -p 5432:5432 -d postgres:15

# Run the setup script
psql -h localhost -U postgres -d ecommerce -f setup.sql

# Start the application
dotnet run

# Test creating orders
curl -X POST https://localhost:7001/orders \
  -H "Content-Type: application/json" \
  -d '{
    "customerName": "Alice Johnson",
    "productName": "Gaming Laptop",
    "amount": 1899.99
  }'

# Test validation errors
curl -X POST https://localhost:7001/orders \
  -H "Content-Type: application/json" \
  -d '{
    "customerName": "",
    "productName": "Invalid Product",
    "amount": -100
  }'

Integration Patterns

Combining Multiple Libraries

The power of Momentum Libraries comes from how they work together:

var builder = WebApplication.CreateBuilder(args);

// Foundation: Service defaults for observability and health
builder.AddServiceDefaults();

// API enhancements: OpenAPI, gRPC, route conventions
builder.AddApiDefaults();

// Extensions: Result types, validation, data access
builder.Services.AddScoped<IOrderService, OrderService>();
builder.Services.AddValidatorsFromAssemblyContaining<Program>();

// Source generators: Automatic DbCommand handling
// (Automatically activated when package is referenced)

// Messaging: Event-driven capabilities
builder.AddKafkaMessaging(builder.Configuration);

var app = builder.Build();

// All the endpoints and middleware are configured
app.MapDefaultEndpoints();
app.MapApiEndpoints();

await app.RunAsync();

Error Handling Patterns

Consistent error handling across your application:

// Service layer
public async Task<Result<Customer>> GetCustomerAsync(Guid id)
{
    var customer = await customerRepository.GetByIdAsync(id);

    return customer switch
    {
        null => Result<Customer>.NotFound("Customer", id.ToString()),
        _ => Result<Customer>.Success(customer)
    };
}

// API layer
app.MapGet("/customers/{id:guid}", async (Guid id, ICustomerService service) =>
{
    var result = await service.GetCustomerAsync(id);

    return result.Match(
        onSuccess: customer => Results.Ok(customer),
        onFailure: errors => Results.BadRequest(errors)
    );
});

Event-Driven Integration

Publish and consume events across services:

// Domain event
[EventTopic("ecommerce.orders.order-created")]
public record OrderCreated(
    [PartitionKey] Guid CustomerId,
    Order Order
);

// Command handler that publishes events
public static async Task<(Result<Order>, OrderCreated?)> Handle(
    CreateOrderCommand command,
    IMessageBus messageBus)
{
    // Business logic...
    var order = await CreateOrderInDatabase(command);

    // Create integration event
    var orderCreated = new OrderCreated(order.CustomerId, order);

    return (Result<Order>.Success(order), orderCreated);
}

// Event handler in another service
public class OrderCreatedHandler
{
    public async Task Handle(OrderCreated orderCreated, CancellationToken cancellationToken)
    {
        // Process the order creation in inventory service
        await inventoryService.ReserveItemsAsync(orderCreated.Order.Items, cancellationToken);
    }
}

Best Practices

1. Start Small, Scale Up

// Begin with essentials
builder.AddServiceDefaults();
builder.Services.AddScoped<IMyService, MyService>();

// Add capabilities as needed
builder.AddApiDefaults();        // When you need enhanced APIs
builder.AddKafkaMessaging();     // When you need events
// Source generators activate automatically

2. Consistent Error Handling

// Always use Result<T> for business operations
public async Task<Result<Customer>> CreateCustomerAsync(CreateCustomerCommand command)
{
    // Validation
    var validationResult = await validator.ValidateAsync(command);
    if (!validationResult.IsValid)
        return Result<Customer>.Failure(validationResult.Errors);

    // Business logic
    try
    {
        var customer = await customerRepository.CreateAsync(command.ToEntity());
        return Result<Customer>.Success(customer.ToModel());
    }
    catch (Exception ex) when (ex is not ValidationException)
    {
        logger.LogError(ex, "Failed to create customer");
        return Result<Customer>.Failure("An error occurred while creating the customer");
    }
}

3. Leverage Source Generation

// Mark database commands for generation
[DbCommand]
public record GetCustomersQuery(int Page, int PageSize) : IQuery<IEnumerable<Customer>>;

// The source generator creates the handler automatically
// Use dependency injection to access the generated handler

4. Configuration Patterns

// Use configuration sections for complex settings
builder.Services.Configure<OrderServiceOptions>(
    builder.Configuration.GetSection("OrderService"));

// Validate configuration at startup
builder.Services.AddOptions<OrderServiceOptions>()
    .Bind(builder.Configuration.GetSection("OrderService"))
    .ValidateDataAnnotations()
    .ValidateOnStart();

Next Steps

Choose your path based on how you're using Momentum:

If You Used the Template

  1. Explore the Generated Solution - Understand what was created
  2. Add Your Business Domain - Replace sample code with your logic
  3. Deploy to Production - Deploy your microservices (coming soon)
  4. Template Options Reference - Complete parameter guide

If You're Using Individual Libraries

  1. Service Configuration Guide - Deep dive into observability, health checks, and resilience
  2. Error Handling Patterns - Master the Result pattern and validation
  3. Database Operations - Learn DbCommand source generation and best practices
  4. Event-Driven Messaging - Build robust event-driven architectures with Kafka
  5. Testing Strategies - Comprehensive testing patterns for Momentum applications

Advanced Topics for Both Approaches

  1. CQRS Implementation - Command/Query separation patterns
  2. Architecture Decisions - Design patterns and architectural guidance
  3. Best Practices - Production-ready patterns and guidelines
  4. Troubleshooting - Common issues and solutions

Coming Soon

We're continuously expanding Momentum to include even more production-ready technologies and patterns:

  • SQL Server - Additional database provider support alongside PostgreSQL
  • k6 for Performance Testing - Automated load testing and performance validation
  • LGTM stack for improved observability - Enhanced monitoring with Loki, Grafana, Tempo, and Mimir
  • Maybe REDIS - Caching and session management capabilities

Support

If you encounter any issues or require assistance, please open an issue on the project's GitHub page.

Contribution

Momentum is designed to be copied and customized, If you've created patterns or improvements that would benefit the broader community, share it, contributions to the template are welcome!

Code of Conduct

Contributor Covenant

This project has adopted the code of conduct defined by the Contributor Covenant to clarify expected behavior in our community. For more information see the Code of Conduct.

Credits and Acknowledgements

Momentum makes use of several outstanding open-source libraries and frameworks. We extend our gratitude to the developers and contributors of these projects:

Core Framework Libraries

  • Wolverine: Next-generation message bus and CQRS framework for .NET, providing elegant command/query handling and message processing capabilities.
  • Mapperly: A .NET source generator for generating object mappings at compile-time, offering zero-overhead and type-safe mapping.
  • Microsoft Orleans: A cross-platform framework for building robust, scalable distributed applications with virtual actors.
  • .NET Aspire: An opinionated, cloud-ready stack for building observable, production-ready distributed applications.

Data & Messaging

  • Dapper: A simple object mapper for .NET with high performance and minimal overhead.
  • linq2db: Fast, lightweight, and type-safe LINQ to SQL implementation for .NET.
  • FluentValidation: A popular .NET library for building strongly-typed validation rules.
  • CloudNative CloudEvents: A specification for describing event data in a common way with Kafka integration.
  • Npgsql: The .NET data provider for PostgreSQL.
  • Liquibase: Database schema change management and version control.

Testing & Quality

  • xUnit v3: Modern, extensible testing framework for .NET applications.
  • Shouldly: Testing framework that focuses on giving great error messages when assertions fail.
  • Testcontainers: A library to support tests with throwaway instances of Docker containers.
  • NSubstitute: A friendly substitute for .NET mocking libraries.
  • NetArchTest: A fluent API for .NET that can enforce architectural rules in unit tests.

Observability & Infrastructure

  • OpenTelemetry: A collection of tools, APIs, and SDKs for instrumenting, generating, collecting, and exporting telemetry data.
  • Serilog: Diagnostic logging library for .NET applications with rich structured event data.
  • Scalar: Modern API documentation with interactive OpenAPI/Swagger support.
  • gRPC: A high-performance, open source universal RPC framework.
  • Orleans Dashboard: Web-based monitoring dashboard for Microsoft Orleans applications.

Code Generation & Utilities

  • OneOf: Discriminated unions for C# with exhaustive matching.
  • Spectre.Console: A .NET library that makes it easier to create beautiful console applications.
  • Fluid: High-performance, secure Liquid templating language for .NET.

Each of these libraries may be licensed differently, so we recommend you review their licenses if you plan to use Momentum in your own projects.

Special thanks to the .NET community and all contributors who help make these tools possible!

This project only uses third-party libraries with permissive licenses (e.g., MIT, Apache 2.0) that are approved for commercial use.


Momentum: Real-world microservices. Modern architecture. Production-ready from day one.

This package has no dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.0.3 120 9/9/2025
0.0.2 119 9/9/2025
0.0.2-preview.6 109 9/9/2025
0.0.2-preview.5 111 9/9/2025
0.0.2-preview.4 106 9/9/2025
0.0.2-preview.3 108 9/9/2025
0.0.2-preview.2 112 9/9/2025
0.0.2-preview.1 124 9/5/2025
0.0.1 183 8/29/2025
0.0.1-pre.23 169 8/29/2025
0.0.1-pre.19 127 8/21/2025
0.0.1-pre.18 121 8/21/2025
0.0.1-pre.17 123 8/21/2025
0.0.1-pre.13 128 8/20/2025
0.0.1-pre.12 132 8/18/2025
0.0.1-pre.6 130 8/18/2025
0.0.1-pre.5 135 8/18/2025
0.0.1-pre.4 138 8/18/2025