{"id":44496134,"url":"https://github.com/vgmello/momentum","last_synced_at":"2026-04-24T15:01:37.574Z","repository":{"id":308634363,"uuid":"1019685971","full_name":"vgmello/momentum","owner":"vgmello","description":"Momentum.Net - Start Building","archived":false,"fork":false,"pushed_at":"2026-04-18T12:13:03.000Z","size":4354,"stargazers_count":3,"open_issues_count":2,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-18T14:12:27.542Z","etag":null,"topics":["csharp","dotnet","dotnet-template","microservice","mmt","momentum"],"latest_commit_sha":null,"homepage":"https://momentumlib.net/","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vgmello.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":".github/SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-07-14T17:56:58.000Z","updated_at":"2026-04-18T12:03:24.000Z","dependencies_parsed_at":"2025-09-23T02:19:34.264Z","dependency_job_id":"a925e02d-7e50-4a16-93e4-46afec67076d","html_url":"https://github.com/vgmello/momentum","commit_stats":null,"previous_names":["vgmello/momentum"],"tags_count":94,"template":false,"template_full_name":null,"purl":"pkg:github/vgmello/momentum","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vgmello%2Fmomentum","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vgmello%2Fmomentum/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vgmello%2Fmomentum/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vgmello%2Fmomentum/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vgmello","download_url":"https://codeload.github.com/vgmello/momentum/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vgmello%2Fmomentum/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32122001,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-22T00:31:26.853Z","status":"online","status_checked_at":"2026-04-22T02:00:05.693Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","dotnet","dotnet-template","microservice","mmt","momentum"],"created_at":"2026-02-13T05:20:07.759Z","updated_at":"2026-04-22T06:04:04.686Z","avatar_url":"https://github.com/vgmello.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Momentum .NET\n\n[![NuGet](https://img.shields.io/nuget/v/Momentum.Extensions.Abstractions?style=flat-square\u0026color=blue)](https://www.nuget.org/packages/Momentum.Extensions.Abstractions)\n[![Downloads](https://img.shields.io/nuget/dt/Momentum.Extensions.Abstractions?style=flat-square)](https://www.nuget.org/packages/Momentum.Extensions.Abstractions)\n[![License](https://img.shields.io/github/license/vgmello/momentum?style=flat-square\u0026color=brightgreen)](https://github.com/vgmello/momentum/blob/main/LICENSE)\n[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/vgmello/momentum/ci.yml?style=flat-square\u0026logo=github\u0026label=CI)](https://github.com/vgmello/momentum/actions/workflows/ci.yml)\n[![Coverage](https://img.shields.io/sonar/coverage/vgmello_momentum?server=https%3A%2F%2Fsonarcloud.io\u0026style=flat-square\u0026logo=sonarqubecloud)](https://sonarcloud.io/summary/overall?id=vgmello_momentum)\n[![Quality Gate](https://img.shields.io/sonar/quality_gate/vgmello_momentum?server=https%3A%2F%2Fsonarcloud.io\u0026style=flat-square\u0026logo=sonarqubecloud)](https://sonarcloud.io/summary/overall?id=vgmello_momentum)\n\nWelcome to **Momentum** - a comprehensive .NET 10 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.\n\n## Quick Start (2 Minutes)\n\nGet a complete microservices solution running in under 2 minutes:\n\n### 1. Install the Template\n\n```bash\n# Install from NuGet (recommended)\ndotnet new install Momentum.Template\n```\n\n### 2. Generate Your Solution\n\n```bash\n# Create a complete microservices solution\ndotnet new mmt -n OrderService --allow-scripts yes\ncd OrderService\n```\n\n### 3. Start Everything with Aspire\n\n```bash\n# Launch the complete application stack\ndotnet run --project src/OrderService.AppHost\n\n# Access the Aspire Dashboard: https://localhost:18110\n# API endpoints: http://localhost:8101 (REST), http://localhost:8102 (gRPC)\n# Documentation: http://localhost:8119\n```\n\n**That's it!** You now have a running microservices solution with:\n\n- ✅ REST and gRPC APIs with sample endpoints\n- ✅ Background event processing with Wolverine\n- ✅ PostgreSQL database with migrations\n- ✅ Apache Kafka messaging\n- ✅ Comprehensive observability\n- ✅ Live documentation\n- ✅ Sample business domain (Cashiers/Invoices)\n\n## Technology Stack\n\nMomentum is built on modern, production-proven technologies:\n\n- **🎯 .NET 10**: Latest framework with performance optimizations\n- **🏗️ .NET Aspire**: Local development orchestration and observability\n- **🎭 Orleans**: Stateful actor-based processing for complex workflows\n- **⚡ Wolverine**: CQRS/MediatR pattern with message handling\n- **🚀 gRPC + REST**: Dual API protocols for performance and compatibility\n- **📡 Apache Kafka**: Event streaming and reliable messaging\n- **🗄️ PostgreSQL**: Robust relational database with JSON support\n- **🔄 Liquibase**: Version-controlled database migrations\n- **📊 OpenTelemetry**: Distributed tracing and observability\n- **🔌 Refit + Refitter**: Type-safe REST API clients with OpenAPI code generation\n- **🧪 Testcontainers**: Real infrastructure for integration testing\n\n## Template System Overview\n\n**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.\n\n**Architecture style**: Domain-Oriented Vertical Slice Architecture (CQRS + Event-Driven), using DDD-inspired boundaries (bounded contexts, domain language, contracts/events) with a pragmatic application-service style.\n\n### **Core Architecture Principles**\n\n- **🎯 Real-World Mirroring**: Code structure corresponds to business operations and processes\n- **🚫 No Smart Objects**: Entities are data records, not self-modifying objects\n- **🏢 Front/Back Office**: Synchronous APIs vs Asynchronous processing\n- **📡 Event-Driven**: Integration events via Kafka with Wolverine message handling\n- **🧭 Pragmatic Domain Boundaries**: Bounded contexts, domain language, and contracts/events without heavy domain object ceremony\n- **🧪 Testing First**: Comprehensive testing with real infrastructure\n\n## Prerequisites\n\nBefore getting started, ensure you have:\n\n- **.NET 10 SDK** - [Download here](https://dotnet.microsoft.com/download/dotnet/10.0)\n- **IDE**: Visual Studio, VS Code with C# Dev Kit, or JetBrains Rider\n- **Local Container Solution (Docker, Rancher, Podman, etc)** - Required for databases, Kafka, and local development\n\n## Template Configuration Options\n\nThe template supports extensive customization through parameters. Here are the most common configurations:\n\n### **Simple API Service**\n\n```bash\n# Generate API-only service\ndotnet new mmt -n PaymentService --api --backoffice false --orleans false --docs false\n```\n\n### **Orleans Processing Engine**\n\n```bash\n# Generate stateful processing service\ndotnet new mmt -n WorkflowEngine --orleans --api false --port 9000\n```\n\n### **Full Stack Solution**\n\n```bash\n# Generate complete solution with custom settings\ndotnet new mmt -n EcommercePlatform --org \"Acme Corp\" --port 7000\n```\n\n### **Minimal Setup**\n\n```bash\n# Clean slate without sample code\ndotnet new mmt -n CleanService --no-sample\n```\n\n### **Available Template Parameters**\n\nThe template offers comprehensive configuration options:\n\n**Core Components:**\n\n- `--api`: REST/gRPC API project (default: true)\n- `--backoffice`: Background processing project (default: true)\n- `--aspire`: .NET Aspire orchestration project (default: true)\n- `--docs`: VitePress documentation project (default: true)\n- `--orleans`: Orleans stateful processing project (default: false)\n\n**Infrastructure:**\n\n- `--kafka`: Apache Kafka messaging (default: true)\n- `--db-config`: Database setup (`default`, `npgsql`, `liquibase`, `none`)\n- `--port`: Base port number (default: 8100)\n\n**Customization:**\n\n- `--org`: Organization name for copyright headers, github, etc\n- `--no-sample`: Exclude sample code (default: false, use `--no-sample` to skip)\n- `--project-only`: Generate only projects without solution files\n- `--libs`: Include Momentum libraries as project references\n- `--lib-name`: Custom prefix to replace \"Momentum\" in library names\n- `--local`: Use local Momentum packages from `libs/Momentum/.local/nuget` (template development)\n\n\u003e [!NOTE]\n\u003e For complete parameter documentation and all available combinations, see the [`template.json`](.template.config/template.json) file and the [Template Options Guide](https://momentumlib.net/guide/template-options/) for detailed use cases and examples.\n\n## Understanding the Generated Solution\n\nThe template generates a production-ready solution with clear separation of concerns:\n\n### **Project Structure**\n\n```\nOrderService/\n├── src/\n│   ├── OrderService.Api/              # REST \u0026 gRPC endpoints\n│   ├── OrderService.BackOffice/        # Event processing\n│   ├── OrderService.BackOffice.Orleans/ # Stateful processing (if enabled)\n│   ├── OrderService.AppHost/           # Aspire orchestration\n│   ├── OrderService/                   # Core domain logic\n│   └── OrderService.Contracts/         # Integration events\n├── infra/\n│   └── OrderService.Database/          # Liquibase migrations\n├── tests/\n│   └── OrderService.Tests/             # Comprehensive testing\n├── docs/                               # VitePress documentation\n└── compose.yml                         # Docker Compose for services\n```\n\n### **Business Domain Organization**\n\nGenerated code follows a Domain-Oriented Vertical Slice approach with Wolverine CQRS patterns and event-driven contracts:\n\n```\nsrc/OrderService/\n├── Cashiers/                  # Sample business domain\n│   ├── Commands/              # Business actions (Wolverine handlers)\n│   ├── Queries/               # Information retrieval (Wolverine handlers)\n│   ├── Data/                  # Database operations\n│   └── Contracts/             # Domain events\n└── Invoices/                  # Another sample domain\n    ├── Commands/              # Commands with validation\n    ├── Queries/               # Queries for data retrieval\n    ├── Data/                  # Database access layer\n    └── Contracts/             # Integration events\n```\n\n### **Port Configuration**\n\nServices use a base port system (default: 8100):\n\n| Service          | HTTP  | HTTPS | gRPC | Purpose               |\n| ---------------- | ----- | ----- | ---- | --------------------- |\n| Aspire Dashboard | 18100 | 18110 | -    | Development dashboard |\n| API              | 8101  | 8111  | 8102 | REST \u0026 gRPC endpoints |\n| BackOffice       | 8103  | 8113  | -    | Background processing |\n| Orleans          | 8104  | 8114  | -    | Stateful processing   |\n| Documentation    | 8119  | -     | -    | VitePress docs        |\n| PostgreSQL       | 54320 | -     | -    | Database              |\n| Kafka            | 59092 | -     | -    | Message broker        |\n\nCustomize the base port with `--port 9000` to use 9001, 9002, etc.\n\n## Individual Libraries Approach\n\nFor 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:\n\n📚 **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.\n\nBuild a simple API service using individual Momentum Libraries when you need to add capabilities to existing projects:\n\n### 1. Create New Project\n\n```bash\n# Create a new ASP.NET Core API project\ndotnet new webapi -n OrderService\ncd OrderService\n\n# Add the essential Momentum packages\ndotnet add package Momentum.ServiceDefaults\ndotnet add package Momentum.ServiceDefaults.Api\ndotnet add package Momentum.Extensions\n```\n\n## Library Integration Results\n\nCongratulations! You've added powerful capabilities to your application:\n\n- ✅ Structured error handling with Result types\n- ✅ Built-in health checks and metrics\n- ✅ OpenTelemetry observability\n- ✅ Structured logging with Serilog\n- ✅ Production-ready service defaults\n\n## Individual Libraries Overview\n\nWhen using libraries individually (rather than the template), each library serves a specific purpose and can be used independently:\n\n### **Momentum.Extensions** - Core Foundation\n\nEssential utilities and patterns for any .NET application.\n\n```bash\ndotnet add package Momentum.Extensions\n```\n\n**Key Features:**\n\n- **ResultOfT Types**: Elegant error handling without exceptions\n- **Validation Integration**: FluentValidation helpers and extensions\n- **Data Access**: Enhanced Dapper extensions and LINQ2DB support\n- **Messaging Abstractions**: Base interfaces for CQRS and event-driven design with Wolverine integration\n\n**Use When:** You want robust error handling and core utilities in any .NET project.\n\n### **Momentum.ServiceDefaults** - Production Readiness\n\nComplete service configuration for Aspire-based applications.\n\n```bash\ndotnet add package Momentum.ServiceDefaults\n```\n\n**Key Features:**\n\n- **Aspire Integration**: Full .NET Aspire service defaults implementation\n- **Observability Stack**: OpenTelemetry + Serilog for monitoring\n- **Health Checks**: Built-in application health monitoring\n- **Resilience**: HTTP client resilience patterns\n- **Service Discovery**: Automatic service resolution\n\n**Use When:** Building microservices, APIs, or any distributed application that needs production-ready configuration.\n\n### **Momentum.ServiceDefaults.Api** - API Enhancements\n\nAdditional features specifically for REST and gRPC APIs.\n\n```bash\ndotnet add package Momentum.ServiceDefaults.Api\n```\n\n**Key Features:**\n\n- **OpenAPI**: Enhanced Swagger documentation with XML docs\n- **gRPC Support**: Service registration and health checks\n- **Route Conventions**: Kebab-case URL transformations\n- **Response Types**: Automatic response type generation\n\n**Use When:** Building REST APIs or gRPC services that need enhanced documentation and conventions.\n\n### **Momentum.Extensions.SourceGenerators** - Code Generation\n\nCompile-time code generation for common patterns.\n\n```bash\ndotnet add package Momentum.Extensions.SourceGenerators\n```\n\n**Key Features:**\n\n- **DbCommand Generation**: Type-safe database command handlers\n- **Zero Runtime Overhead**: All generation happens at compile time\n- **IDE Integration**: Generated code appears in IntelliSense\n- **Customizable**: Configure generation through attributes and MSBuild properties\n\n**Use When:** You want to eliminate boilerplate code and ensure type safety for database operations.\n\n### **Momentum.Extensions.Messaging.Kafka** - Event-Driven Architecture\n\nKafka integration with CloudEvents standard support.\n\n```bash\ndotnet add package Momentum.Extensions.Messaging.Kafka\n```\n\n**Key Features:**\n\n- **CloudEvents**: Standards-compliant event serialization\n- **Kafka Integration**: Producer and consumer patterns\n- **Partition Key Support**: Automatic partitioning strategies\n- **Observability**: Built-in metrics and tracing\n\n**Use When:** Building event-driven microservices that need reliable messaging.\n\n## Advanced Library Integration Example\n\nWhen using individual libraries, here's how to build a more complete application that demonstrates library integration:\n\n### 1. Setup Project\n\n```bash\n# Create new project\ndotnet new webapi -n EcommerceService\ncd EcommerceService\n\n# Add comprehensive Momentum packages\ndotnet add package Momentum.ServiceDefaults\ndotnet add package Momentum.Extensions\ndotnet add package Momentum.Extensions.SourceGenerators\ndotnet add package Npgsql  # For PostgreSQL\ndotnet add package FluentValidation.DependencyInjectionExtensions\n```\n\n### 2. Database Models and Commands\n\nCreate `Domain/Orders/Order.cs`:\n\n```csharp\nnamespace EcommerceService.Domain.Orders;\n\n// Database entity\npublic class OrderEntity\n{\n    public Guid Id { get; set; }\n    public string CustomerName { get; set; } = string.Empty;\n    public string ProductName { get; set; } = string.Empty;\n    public decimal Amount { get; set; }\n    public DateTime CreatedAt { get; set; }\n    public DateTime UpdatedAt { get; set; }\n}\n\n// Public model\npublic record Order(\n    Guid Id,\n    string CustomerName,\n    string ProductName,\n    decimal Amount,\n    DateTime CreatedAt\n);\n\n// Extension for conversion\npublic static class OrderExtensions\n{\n    public static Order ToModel(this OrderEntity entity) =\u003e new(\n        entity.Id,\n        entity.CustomerName,\n        entity.ProductName,\n        entity.Amount,\n        entity.CreatedAt\n    );\n}\n```\n\n### 3. Commands with Validation\n\nCreate `Domain/Orders/Commands/CreateOrder.cs`:\n\n```csharp\nusing FluentValidation;\nusing Momentum.Extensions.Abstractions.Messaging;\nusing Momentum.Extensions;\n\nnamespace EcommerceService.Domain.Orders.Commands;\n\npublic record CreateOrderCommand(\n    string CustomerName,\n    string ProductName,\n    decimal Amount\n) : ICommand\u003cResult\u003cOrder\u003e\u003e;\n\npublic class CreateOrderValidator : AbstractValidator\u003cCreateOrderCommand\u003e\n{\n    public CreateOrderValidator()\n    {\n        RuleFor(x =\u003e x.CustomerName)\n            .NotEmpty()\n            .WithMessage(\"Customer name is required\")\n            .MinimumLength(2)\n            .WithMessage(\"Customer name must be at least 2 characters\")\n            .MaximumLength(100)\n            .WithMessage(\"Customer name cannot exceed 100 characters\");\n\n        RuleFor(x =\u003e x.ProductName)\n            .NotEmpty()\n            .WithMessage(\"Product name is required\")\n            .MaximumLength(200)\n            .WithMessage(\"Product name cannot exceed 200 characters\");\n\n        RuleFor(x =\u003e x.Amount)\n            .GreaterThan(0)\n            .WithMessage(\"Amount must be greater than zero\")\n            .LessThanOrEqualTo(1000000)\n            .WithMessage(\"Amount cannot exceed $1,000,000\");\n    }\n}\n```\n\n### 4. Database Commands with Source Generation\n\nCreate `Domain/Orders/Data/OrderDbCommands.cs`:\n\n```csharp\nusing Dapper;\nusing Momentum.Extensions.Abstractions.Dapper;\nusing Momentum.Extensions.Abstractions.Messaging;\nusing System.Data;\n\nnamespace EcommerceService.Domain.Orders.Data;\n\npublic static class CreateOrderDbCommandHandler\n{\n    [DbCommand]\n    public record DbCommand(OrderEntity Order) : ICommand\u003cOrderEntity\u003e;\n\n    public static async Task\u003cOrderEntity\u003e Handle(\n        DbCommand command,\n        IDbConnection db,\n        CancellationToken cancellationToken)\n    {\n        const string sql = \"\"\"\n            INSERT INTO orders (id, customer_name, product_name, amount, created_at, updated_at)\n            VALUES (@Id, @CustomerName, @ProductName, @Amount, @CreatedAt, @UpdatedAt)\n            RETURNING *;\n            \"\"\";\n\n        var order = command.Order;\n        return await db.QuerySingleAsync\u003cOrderEntity\u003e(sql, new\n        {\n            order.Id,\n            order.CustomerName,\n            order.ProductName,\n            order.Amount,\n            order.CreatedAt,\n            order.UpdatedAt\n        });\n    }\n}\n\npublic static class GetOrderDbCommandHandler\n{\n    [DbCommand]\n    public record DbCommand(Guid OrderId) : ICommand\u003cOrderEntity?\u003e;\n\n    public static async Task\u003cOrderEntity?\u003e Handle(\n        DbCommand command,\n        IDbConnection db,\n        CancellationToken cancellationToken)\n    {\n        const string sql = \"SELECT * FROM orders WHERE id = @OrderId\";\n        return await db.QuerySingleOrDefaultAsync\u003cOrderEntity\u003e(sql, new { command.OrderId });\n    }\n}\n```\n\n### 5. Business Logic Handler\n\nCreate `Domain/Orders/Commands/CreateOrderHandler.cs`:\n\n```csharp\nusing EcommerceService.Domain.Orders.Data;\nusing FluentValidation;\nusing Momentum.Extensions;\n\nnamespace EcommerceService.Domain.Orders.Commands;\n\npublic static class CreateOrderCommandHandler\n{\n    public static async Task\u003cResult\u003cOrder\u003e\u003e Handle(\n        CreateOrderCommand command,\n        IValidator\u003cCreateOrderCommand\u003e validator,\n        IMessageBus messageBus,\n        CancellationToken cancellationToken)\n    {\n        // Validate input\n        var validationResult = await validator.ValidateAsync(command, cancellationToken);\n        if (!validationResult.IsValid)\n        {\n            return validationResult.Errors;\n        }\n\n        // Create database entity\n        var orderEntity = new OrderEntity\n        {\n            Id = Guid.CreateVersion7(),\n            CustomerName = command.CustomerName,\n            ProductName = command.ProductName,\n            Amount = command.Amount,\n            CreatedAt = DateTime.UtcNow,\n            UpdatedAt = DateTime.UtcNow\n        };\n\n        // Save to database using generated command\n        var dbCommand = new CreateOrderDbCommandHandler.DbCommand(orderEntity);\n        var savedOrder = await messageBus.InvokeCommandAsync(dbCommand, cancellationToken);\n\n        return savedOrder.ToModel();\n    }\n}\n```\n\n### 6. API Configuration\n\nUpdate `Program.cs`:\n\n```csharp\nusing EcommerceService.Domain.Orders.Commands;\nusing FluentValidation;\nusing Momentum.Extensions;\nusing Momentum.ServiceDefaults;\nusing Momentum.ServiceDefaults.Api;\nusing Momentum.ServiceDefaults.Api.OpenApi.Extensions;\nusing Momentum.ServiceDefaults.HealthChecks;\nusing Npgsql;\nusing System.Data;\n\nvar builder = WebApplication.CreateBuilder(args);\n\n// Add Momentum service defaults\nbuilder.AddServiceDefaults();\nbuilder.AddApiServiceDefaults(requireAuth: false);\nbuilder.Services.AddOpenApi(options =\u003e options.ConfigureOpenApiDefaults());\n\n// Add database connection\nbuilder.Services.AddScoped\u003cIDbConnection\u003e(provider =\u003e\n{\n    var connectionString = builder.Configuration.GetConnectionString(\"DefaultConnection\")\n        ?? \"Host=localhost;Database=ecommerce;Username=postgres;Password=password\";\n    return new NpgsqlConnection(connectionString);\n});\n\n// Add FluentValidation\nbuilder.Services.AddValidatorsFromAssemblyContaining\u003cCreateOrderValidator\u003e();\n\nvar app = builder.Build();\n\n// Configure pipeline\napp.ConfigureApiUsingDefaults();\napp.MapDefaultHealthCheckEndpoints();\n\n// Add API endpoints\napp.MapPost(\"/orders\", async (\n    CreateOrderCommand command,\n    IValidator\u003cCreateOrderCommand\u003e validator,\n    IMessageBus messageBus,\n    CancellationToken cancellationToken) =\u003e\n{\n    var result = await CreateOrderCommandHandler.Handle(command, validator, messageBus, cancellationToken);\n\n    return result.Match(\n        onSuccess: order =\u003e Results.Created($\"/orders/{order.Id}\", order),\n        onFailure: errors =\u003e Results.BadRequest(errors.Select(e =\u003e new { e.PropertyName, e.ErrorMessage }))\n    );\n});\n\napp.MapGet(\"/orders/{id:guid}\", async (\n    Guid id,\n    IMessageBus messageBus,\n    CancellationToken cancellationToken) =\u003e\n{\n    var dbCommand = new GetOrderDbCommandHandler.DbCommand(id);\n    var orderEntity = await messageBus.InvokeCommandAsync(dbCommand, cancellationToken);\n\n    return orderEntity is not null\n        ? Results.Ok(orderEntity.ToModel())\n        : Results.NotFound();\n});\n\nawait app.RunAsync();\n```\n\n### 7. Database Setup\n\nCreate a simple migration script `setup.sql`:\n\n```sql\n-- Create orders table\nCREATE TABLE IF NOT EXISTS orders (\n    id UUID PRIMARY KEY,\n    customer_name VARCHAR(100) NOT NULL,\n    product_name VARCHAR(200) NOT NULL,\n    amount DECIMAL(10,2) NOT NULL,\n    created_at TIMESTAMP WITH TIME ZONE NOT NULL,\n    updated_at TIMESTAMP WITH TIME ZONE NOT NULL\n);\n\n-- Create index for performance\nCREATE INDEX IF NOT EXISTS idx_orders_created_at ON orders(created_at);\n```\n\n### 8. Configuration\n\nCreate `appsettings.Development.json`:\n\n```json\n{\n    \"ConnectionStrings\": {\n        \"DefaultConnection\": \"Host=localhost;Database=ecommerce;Username=postgres;Password=password\"\n    },\n    \"Logging\": {\n        \"LogLevel\": {\n            \"Default\": \"Information\",\n            \"Microsoft.AspNetCore\": \"Warning\"\n        }\n    }\n}\n```\n\n### 9. Run and Test\n\n```bash\n# Start PostgreSQL (using Docker)\ndocker run --name postgres-ecommerce -e POSTGRES_PASSWORD=password -e POSTGRES_DB=ecommerce -p 5432:5432 -d postgres:15\n\n# Run the setup script\npsql -h localhost -U postgres -d ecommerce -f setup.sql\n\n# Start the application\ndotnet run\n\n# Test creating orders\ncurl -X POST https://localhost:7001/orders \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"customerName\": \"Alice Johnson\",\n    \"productName\": \"Gaming Laptop\",\n    \"amount\": 1899.99\n  }'\n\n# Test validation errors\ncurl -X POST https://localhost:7001/orders \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"customerName\": \"\",\n    \"productName\": \"Invalid Product\",\n    \"amount\": -100\n  }'\n```\n\n## Integration Patterns\n\n### Combining Multiple Libraries\n\nThe power of Momentum Libraries comes from how they work together:\n\n```csharp\nvar builder = WebApplication.CreateBuilder(args);\n\n// Foundation: Service defaults for observability and health\nbuilder.AddServiceDefaults();\n\n// API enhancements: OpenAPI, gRPC, route conventions\nbuilder.AddApiServiceDefaults(requireAuth: false);\nbuilder.Services.AddOpenApi(options =\u003e options.ConfigureOpenApiDefaults());\n\n// Extensions: Result types, validation, data access\nbuilder.Services.AddScoped\u003cIOrderService, OrderService\u003e();\nbuilder.Services.AddValidatorsFromAssemblyContaining\u003cProgram\u003e();\n\n// Source generators: Automatic DbCommand handling\n// (Automatically activated when package is referenced)\n\n// Messaging: Event-driven capabilities\nbuilder.AddKafkaMessagingExtensions();\n\nvar app = builder.Build();\n\n// All the endpoints and middleware are configured\napp.ConfigureApiUsingDefaults();\napp.MapDefaultHealthCheckEndpoints();\n\nawait app.RunAsync();\n```\n\n### Error Handling Patterns\n\nConsistent error handling across your application:\n\n```csharp\n// Service layer\npublic async Task\u003cResult\u003cCustomer\u003e\u003e GetCustomerAsync(Guid id)\n{\n    var customer = await customerRepository.GetByIdAsync(id);\n\n    return customer is null\n        ? [new ValidationFailure(nameof(id), \"Customer not found\")]\n        : customer;\n}\n\n// API layer\napp.MapGet(\"/customers/{id:guid}\", async (Guid id, ICustomerService service) =\u003e\n{\n    var result = await service.GetCustomerAsync(id);\n\n    return result.Match(\n        onSuccess: customer =\u003e Results.Ok(customer),\n        onFailure: errors =\u003e Results.BadRequest(errors)\n    );\n});\n```\n\n### Event-Driven Integration\n\nPublish and consume events across services:\n\n```csharp\n// Domain event\n[EventTopic(\"ecommerce.orders.order-created\")]\npublic record OrderCreated(\n    [PartitionKey] Guid OrderId,\n    Order Order\n);\n\n// Command handler that publishes events\npublic static async Task\u003c(Result\u003cOrder\u003e, OrderCreated?)\u003e Handle(\n    CreateOrderCommand command,\n    IMessageBus messageBus)\n{\n    // Business logic...\n    var order = await CreateOrderInDatabase(command);\n\n    // Create integration event\n    var orderCreated = new OrderCreated(order.Id, order);\n\n    return (order, orderCreated);\n}\n\n// Event handler in another service\npublic class OrderCreatedHandler\n{\n    public async Task Handle(OrderCreated orderCreated, CancellationToken cancellationToken)\n    {\n        // Process the order creation in another bounded context\n        await analyticsService.TrackOrderCreatedAsync(orderCreated.Order, cancellationToken);\n    }\n}\n```\n\n## Best Practices\n\n### 1. **Start Small, Scale Up**\n\n```csharp\n// Begin with essentials\nbuilder.AddServiceDefaults();\nbuilder.Services.AddScoped\u003cIMyService, MyService\u003e();\n\n// Add capabilities as needed\nbuilder.AddApiServiceDefaults(requireAuth: false); // When you need enhanced APIs\nbuilder.AddKafkaMessagingExtensions();             // When you need events\n// Source generators activate automatically\n```\n\n### 2. **Consistent Error Handling**\n\n```csharp\n// Always use Result\u003cT\u003e for business operations\npublic async Task\u003cResult\u003cCustomer\u003e\u003e CreateCustomerAsync(CreateCustomerCommand command)\n{\n    // Validation\n    var validationResult = await validator.ValidateAsync(command);\n    if (!validationResult.IsValid)\n        return validationResult.Errors;\n\n    // Business logic\n    try\n    {\n        var customer = await customerRepository.CreateAsync(command.ToEntity());\n        return customer.ToModel();\n    }\n    catch (Exception ex) when (ex is not ValidationException)\n    {\n        logger.LogError(ex, \"Failed to create customer\");\n        return [new ValidationFailure(string.Empty, \"An error occurred while creating the customer\")];\n    }\n}\n```\n\n### 3. **Leverage Source Generation**\n\n```csharp\n// Mark database commands for generation\n[DbCommand]\npublic record GetCustomersQuery(int Page, int PageSize) : IQuery\u003cIEnumerable\u003cCustomer\u003e\u003e;\n\n// The source generator creates the handler automatically\n// Use dependency injection to access the generated handler\n```\n\n### 4. **Configuration Patterns**\n\n```csharp\n// Use configuration sections for complex settings\nbuilder.Services.Configure\u003cOrderServiceOptions\u003e(\n    builder.Configuration.GetSection(\"OrderService\"));\n\n// Validate configuration at startup\nbuilder.Services.AddOptions\u003cOrderServiceOptions\u003e()\n    .Bind(builder.Configuration.GetSection(\"OrderService\"))\n    .ValidateDataAnnotations()\n    .ValidateOnStart();\n```\n\n## Next Steps\n\nChoose your path based on how you're using Momentum:\n\n### **If You Used the Template**\n\n1. **[Explore the Generated Solution](https://momentumlib.net/guide/template-walkthrough/)** - Understand what was created\n2. **[Add Your Business Domain](https://momentumlib.net/guide/adding-domains/)** - Replace sample code with your logic\n3. **Deploy to Production** - Deploy your microservices (coming soon)\n4. **[Template Options Reference](https://momentumlib.net/guide/template-options/)** - Complete parameter guide\n\n### **If You're Using Individual Libraries**\n\n1. **[Service Configuration Guide](https://momentumlib.net/guide/service-configuration/)** - Deep dive into observability, health checks, and resilience\n2. **[Error Handling Patterns](https://momentumlib.net/guide/error-handling)** - Master the Result pattern and validation\n3. **[Database Operations](https://momentumlib.net/guide/database/)** - Learn DbCommand source generation and best practices\n4. **[Event-Driven Messaging](https://momentumlib.net/guide/messaging/)** - Build robust event-driven architectures with Kafka\n5. **[Testing Strategies](https://momentumlib.net/guide/testing/)** - Comprehensive testing patterns for Momentum applications\n\n### **Advanced Topics for Both Approaches**\n\n6. **[CQRS Implementation](https://momentumlib.net/guide/cqrs/)** - Command/Query separation patterns\n7. **[Architecture Decisions](https://momentumlib.net/guide/arch/)** - Design patterns and architectural guidance\n8. **[Best Practices](https://momentumlib.net/guide/best-practices)** - Production-ready patterns and guidelines\n9. **[Troubleshooting](https://momentumlib.net/guide/troubleshooting)** - Common issues and solutions\n\n## Coming Soon\n\nWe're continuously expanding Momentum to include even more production-ready technologies and patterns:\n\n- **SQL Server** - Additional database provider support alongside PostgreSQL\n- **k6 for Performance Testing** - Automated load testing and performance validation\n- **LGTM stack for improved observability** - Enhanced monitoring with Loki, Grafana, Tempo, and Mimir\n- **Maybe REDIS** - Caching and session management capabilities\n\n## Support\n\nIf you encounter any issues or require assistance, please [open an issue](https://github.com/vgmello/momentum/issues) on the project's GitHub page.\n\n## Contribution\n\nMomentum 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!\n\n## Code of Conduct\n\n[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-3.0-4baaaa.svg)](https://www.contributor-covenant.org/version/3/0/code_of_conduct/)\n\nThis project has adopted the code of conduct defined by the [Contributor Covenant](https://www.contributor-covenant.org/) to clarify expected behavior in our community. For more information see the [Code of Conduct](CODE_OF_CONDUCT.MD).\n\n## Credits and Acknowledgements\n\nMomentum makes use of several outstanding open-source libraries and frameworks. We extend our gratitude to the developers and contributors of these projects:\n\n### Core Framework Libraries\n\n- **[Wolverine](https://wolverinefx.io/)**: Next-generation message bus and CQRS framework for .NET, providing elegant command/query handling and message processing capabilities.\n- **[Mapperly](https://github.com/riok/mapperly)**: A .NET source generator for generating object mappings at compile-time, offering zero-overhead and type-safe mapping.\n- **[Microsoft Orleans](https://dotnet.github.io/orleans/)**: A cross-platform framework for building robust, scalable distributed applications with virtual actors.\n- **[.NET Aspire](https://github.com/dotnet/aspire)**: An opinionated, cloud-ready stack for building observable, production-ready distributed applications.\n- **[Asp.Versioning](https://github.com/dotnet/aspnet-api-versioning)**: API versioning for ASP.NET Core with support for URL, query string, and header-based versioning.\n\n### Data \u0026 Messaging\n\n- **[Dapper](https://github.com/DapperLib/Dapper)**: A simple object mapper for .NET with high performance and minimal overhead.\n- **[linq2db](https://linq2db.github.io/)**: Fast, lightweight, and type-safe LINQ to SQL implementation for .NET.\n- **[FluentValidation](https://fluentvalidation.net/)**: A popular .NET library for building strongly-typed validation rules.\n- **[CloudNative CloudEvents](https://cloudevents.io/)**: A specification for describing event data in a common way with Kafka integration.\n- **[Npgsql](https://www.npgsql.org/)**: The .NET data provider for PostgreSQL.\n- **[Liquibase](https://www.liquibase.com/)**: Database schema change management and version control.\n\n### API Client Generation\n\n- **[Refit](https://github.com/reactiveui/refit)**: Automatic type-safe REST library for .NET that turns REST APIs into live interfaces.\n- **[Refitter](https://github.com/christianhelle/refitter)**: OpenAPI client code generation via MSBuild, producing Refit interfaces and contracts from OpenAPI specifications at build time.\n\n### Testing \u0026 Quality\n\n- **[xUnit v3](https://xunit.net/)**: Modern, extensible testing framework for .NET applications.\n- **[Shouldly](https://docs.shouldly.org/)**: Testing framework that focuses on giving great error messages when assertions fail.\n- **[Testcontainers](https://dotnet.testcontainers.org/)**: A library to support tests with throwaway instances of Docker containers.\n- **[NSubstitute](https://nsubstitute.github.io/)**: A friendly substitute for .NET mocking libraries.\n- **[NetArchTest](https://github.com/BenMorris/NetArchTest)**: A fluent API for .NET that can enforce architectural rules in unit tests.\n- **[Bogus](https://github.com/bchavez/Bogus)**: A simple fake data generator for .NET, useful for creating realistic test data.\n- **[coverlet](https://github.com/coverlet-coverage/coverlet)**: Cross-platform code coverage library for .NET with support for line, branch, and method coverage.\n- **[SonarAnalyzer](https://github.com/SonarSource/sonar-dotnet)**: Static code analysis for C# to detect bugs, vulnerabilities, and code smells.\n\n### Observability \u0026 Infrastructure\n\n- **[OpenTelemetry](https://opentelemetry.io/)**: A collection of tools, APIs, and SDKs for instrumenting, generating, collecting, and exporting telemetry data.\n- **[Serilog](https://serilog.net/)**: Diagnostic logging library for .NET applications with rich structured event data.\n- **[Scalar](https://github.com/scalar/scalar)**: Modern API documentation with interactive OpenAPI/Swagger support.\n- **[gRPC](https://grpc.io/)**: A high-performance, open source universal RPC framework.\n- **[Orleans Dashboard](https://github.com/OrleansContrib/OrleansDashboard)**: Community-built web-based monitoring dashboard for Orleans applications.\n\n### Code Generation \u0026 Utilities\n\n- **[OneOf](https://github.com/mcintyre321/OneOf)**: Discriminated unions for C# with exhaustive matching.\n- **[Spectre.Console](https://spectreconsole.net/)**: A .NET library that makes it easier to create beautiful console applications.\n- **[Fluid](https://github.com/sebastienros/fluid)**: High-performance, secure Liquid templating language for .NET.\n\nEach of these libraries may be licensed differently, so we recommend you review their licenses if you plan to use Momentum in your own projects.\n\nSpecial thanks to the .NET community and all contributors who help make these tools possible!\n\n\u003e This project only uses third-party libraries with permissive licenses (e.g., MIT, Apache 2.0) that are approved for commercial use.\n\n---\n\n_Momentum: Real-world microservices. Modern architecture. Production-ready from day one._\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvgmello%2Fmomentum","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvgmello%2Fmomentum","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvgmello%2Fmomentum/lists"}