Skip to main content

Introduction

AspNetRun Microservices is a reference application demonstrating modern .NET microservices architecture patterns. The project showcases multiple architectural approaches, allowing you to choose the pattern that best fits your domain complexity.

Architecture Patterns

This project implements three distinct architectural patterns across different services:

Clean Architecture + DDD

Used in Ordering service for complex business domains

Vertical Slice

Used in Catalog service for simpler CRUD operations

CQRS Pattern

Applied across all services for separating reads and writes

System Architecture

Service Breakdown

Catalog Service

Pattern: Vertical Slice ArchitectureDatabase: PostgreSQL with Marten (Document DB)Location: src/Services/Catalog/Catalog.API
The Catalog service demonstrates the Vertical Slice pattern, organizing code by features rather than technical layers. Each feature (CreateProduct, GetProducts, etc.) contains all necessary code in a single directory. Key Characteristics:
  • Simple domain model without complex business rules
  • Feature-based organization
  • Minimal ceremony for CRUD operations

Ordering Service

Pattern: Clean Architecture + Domain-Driven DesignDatabase: SQL Server with Entity Framework CoreLocation: src/Services/Ordering/
The Ordering service showcases Clean Architecture with DDD tactical patterns, suitable for complex business domains with rich domain logic. Key Characteristics:
  • Layered architecture (Domain, Application, Infrastructure, API)
  • Rich domain models with entities, value objects, and aggregates
  • Domain events for side effects
  • Separation of concerns with clear dependencies

Basket Service

Pattern: Simple CQRSDatabase: Redis for distributed cachingLocation: src/Services/Basket/Basket.API
The Basket service implements a lightweight CQRS pattern with Redis for high-performance caching.

Discount Service

Pattern: gRPC ServiceDatabase: SQLiteLocation: src/Services/Discount/Discount.Grpc
Demonstrates inter-service communication using gRPC for high-performance scenarios.

Cross-Cutting Concerns

BuildingBlocks

The src/BuildingBlocks directory contains shared abstractions and implementations used across all services:
  • CQRS Abstractions: ICommand, IQuery, ICommandHandler, IQueryHandler
  • Behaviors: Logging, Validation, and other cross-cutting concerns
  • Messaging: Integration event definitions and MassTransit configuration
  • Exception Handling: Custom exception types and global handlers
  • Pagination: Reusable pagination contracts
using MediatR;

namespace BuildingBlocks.CQRS;

public interface ICommand : ICommand<Unit>
{
}

public interface ICommand<out TResponse> : IRequest<TResponse>
{
}

API Gateway

The project uses YARP (Yet Another Reverse Proxy) as a lightweight, high-performance API gateway:
  • Routes external requests to appropriate microservices
  • Provides a single entry point for clients
  • Handles cross-cutting concerns like CORS
Location: src/ApiGateways/YarpApiGateway

Communication Patterns

Synchronous Communication

  • HTTP/REST: Client-to-service and service-to-service via API Gateway
  • gRPC: High-performance inter-service communication (Basket → Discount)

Asynchronous Communication

  • Message Broker: RabbitMQ with MassTransit
  • Integration Events: BasketCheckoutEvent published when checkout occurs
  • Event Handlers: Ordering service subscribes to basket events

Design Principles

Each service is independent with its own database, allowing teams to work autonomously and deploy independently.
Services are focused on specific business capabilities (Catalog, Ordering, Basket).
High-level modules don’t depend on low-level modules. Both depend on abstractions (interfaces).
Complex domains (Ordering) use tactical DDD patterns: Aggregates, Entities, Value Objects, Domain Events.

Technology Stack

CategoryTechnology
Framework.NET 8
API StyleMinimal APIs with Carter
MediatorMediatR for CQRS
ValidationFluentValidation
ORMEntity Framework Core, Marten
DatabasesSQL Server, PostgreSQL, Redis, SQLite
MessagingRabbitMQ with MassTransit
API GatewayYARP
MappingMapster
ContainerizationDocker

When to Use Each Pattern

Use Clean Architecture + DDD When:

  • Complex business logic and rules
  • Rich domain models
  • Long-lived projects
  • Multiple teams
  • Domain events needed

Use Vertical Slice When:

  • Simple CRUD operations
  • Small to medium projects
  • Rapid development needed
  • Minimal business logic
  • Quick iterations

Next Steps

Explore Microservices Pattern

Learn about microservices principles and implementation

Study Clean Architecture

Deep dive into the Ordering service architecture

Understand DDD

Learn Domain-Driven Design tactical patterns

CQRS Implementation

See how CQRS is implemented across services

Build docs developers (and LLMs) love