A production-ready .NET Core microservices architecture featuring comprehensive caching, fault tolerance, authentication, and async messaging.
- User Service (Port 5001) - User management with CRUD operations
- Order Service (Port 5002) - Order processing and business logic
- Notification Service (Port 5003) - Async event-driven notifications
- Identity Service (Port 5004) - Authentication and authorization (IdentityServer)
- API Gateway (Port 5000) - YARP reverse proxy with auth integration
- Redis - Distributed caching layer
- RabbitMQ - Message bus for async communication
- SQL Server - Database for Identity Service
- Jaeger - Distributed tracing
- Prometheus - Metrics monitoring
- Docker/Kubernetes - Full containerization and orchestration
- Common - Shared models, interfaces, and utilities
- Caching - Redis caching abstraction with fallback support
- EventBus - RabbitMQ integration for event-driven architecture
- Saga - Orchestration-based saga pattern for distributed transactions
- Outbox - Transactional outbox pattern for reliable event publishing
- Cache-aside pattern with automatic fallback
- TTL-based expiration (configurable per service)
- Cache invalidation on data mutations
- GetOrSet pattern for efficient cache population
Example usage in UserServiceImpl.cs:
var cachedUser = await _cache.GetAsync<User>(cacheKey);
if (cachedUser != null) return ApiResponse<User>.SuccessResponse(cachedUser);All four resilience patterns implemented for HTTP inter-service communication:
- Opens after 50% failure rate (5 min requests)
- Breaks for 30 seconds
- Prevents cascading failures
- 3 retry attempts with jitter
- Exponential delay: ~2s, ~4s, ~8s
- Handles transient failures
- 10s per attempt timeout
- 30s total request timeout
- Prevents resource exhaustion
- Max 10 concurrent requests
- Queue limit: 5 requests
- Prevents thread pool exhaustion
See POLLY-RESILIENCE.md for configuration details.
- OAuth 2.0 / OpenID Connect via IdentityServer
- Client credentials flow for service-to-service auth
- JWT token validation across all services
- Centralized identity management
The solution implements both synchronous and asynchronous communication patterns:
- UserService → OrderService: Fetch user's orders for profile aggregation
- OrderService → UserService: Validate user exists before creating order
Features:
- Named HttpClient with connection pooling
- All 4 Polly resilience patterns applied
- Graceful degradation on service unavailability
- Comprehensive error handling and logging
See HTTPCLIENT-USAGE.md for implementation details.
- UserCreatedEvent: User registration notifications
- OrderCreatedEvent: Order placement notifications
- OrderStatusChangedEvent: Order status updates
Event Flow:
UserService → UserCreatedEvent → NotificationService
OrderService → OrderCreatedEvent → NotificationService
OrderService → OrderStatusChangedEvent → NotificationService
- Orchestration-based sagas for distributed transactions
- Compensating transactions for automatic rollback
- Transactional outbox for guaranteed event delivery
- At-least-once delivery semantics
- Idempotency support for exactly-once processing (cache or database-based)
OrderSaga Flow:
1. CreateOrder → 2. ProcessPayment → 3. ReserveInventory → 4. SendNotification
↓ Failure ↓ Compensation
Refund ← Delete Order ← Release Inventory
Idempotency:
- Each event has unique idempotency key
- Prevents duplicate processing on retries
- Choice of Redis (fast) or database (durable) storage
See SAGA-PATTERN.md and IDEMPOTENCY-GUIDE.md for detailed documentation.
- Single entry point for all services
- Reverse proxy routing to backend services
- Authentication integration with Identity Service
- Load balancing support
EnterpriseMicroservices/
├── src/
│ ├── BuildingBlocks/
│ │ ├── Common/ # Shared models and interfaces
│ │ ├── Caching/ # Redis caching abstraction
│ │ ├── EventBus/ # RabbitMQ integration
│ │ ├── Saga/ # Saga orchestration pattern
│ │ └── Outbox/ # Transactional outbox pattern
│ ├── Services/
│ │ ├── UserService/ # User management service
│ │ ├── OrderService/ # Order processing with saga
│ │ ├── NotificationService/ # Notification service
│ │ └── IdentityService/ # Authentication (IdentityServer)
│ └── Gateway/ # API Gateway (YARP)
├── k8s/ # Kubernetes deployment
│ ├── base/ # Base Kustomize configurations
│ │ ├── services/ # Service deployments
│ │ ├── infrastructure/ # Redis, RabbitMQ, SQL, Jaeger, Prometheus
│ │ ├── hpa/ # Horizontal Pod Autoscalers
│ │ └── network-policies/ # Zero-trust network security
│ └── overlays/ # Environment-specific overrides
│ ├── development/
│ └── production/
├── Docs/ # Documentation
├── docker-compose.yml # Docker orchestration
└── EnterpriseMicroservices.sln # Solution file
- .NET 10.0 SDK
- Docker Desktop
- (Optional) Visual Studio 2025 or VS Code
-
Build and start all services:
docker-compose up --build
-
Access the services:
- API Gateway: http://localhost:5000
- Identity Service: http://localhost:5004/.well-known/openid-configuration
- User Service: http://localhost:5001
- Order Service: http://localhost:5002
- Notification Service: http://localhost:5003
- RabbitMQ Management: http://localhost:15672 (guest/guest)
-
Stop all services:
docker-compose down
Prerequisites:
- Kubernetes cluster (minikube, kind, Docker Desktop, or cloud)
- Metrics Server (required for HPA)
- CNI with NetworkPolicy support (Calico, Cilium, Weave Net)
# Development deployment
kubectl apply -k k8s/overlays/development
# Production deployment
kubectl apply -k k8s/overlays/production
# Watch pods
kubectl get pods -n microservices -w
# View HPA status
kubectl get hpa -n microservices
# Access via port-forward
kubectl port-forward svc/apigateway 5000:5000 -n microservicesSee Docs/kubernetes-deployment.md for detailed K8s deployment guide.
-
Start infrastructure services:
docker-compose up redis rabbitmq sqlserver
-
Run each service:
# Terminal 1 - Identity Service (start first) cd src/Services/IdentityService dotnet run # Terminal 2 - User Service cd src/Services/UserService dotnet run # Terminal 3 - Order Service cd src/Services/OrderService dotnet run # Terminal 4 - Notification Service cd src/Services/NotificationService dotnet run # Terminal 5 - API Gateway cd src/Gateway dotnet run
Via API Gateway (http://localhost:5000)
GET /api/users- Get all usersGET /api/users/{id}- Get user by IDGET /api/users/{id}/with-orders- Get user with orders (inter-service call)POST /api/users- Create new userPUT /api/users/{id}- Update userDELETE /api/users/{id}- Delete user
GET /api/orders- Get all ordersGET /api/orders/{id}- Get order by IDGET /api/orders/user/{userId}- Get orders by user IDPOST /api/orders- Create new orderPATCH /api/orders/{id}/status- Update order statusDELETE /api/orders/{id}- Cancel order
POST /api/ordersaga- Create order with saga pattern- Executes: CreateOrder → ProcessPayment → ReserveInventory → SendNotification
- Auto-compensation on failure
curl -X POST http://localhost:5000/api/users \
-H "Content-Type: application/json" \
-d '{
"firstName": "John",
"lastName": "Doe",
"email": "john.doe@example.com",
"department": "Engineering",
"role": "Developer"
}'curl -X POST http://localhost:5000/api/orders \
-H "Content-Type: application/json" \
-d '{
"userId": "{user-id-from-step-1}",
"items": [
{
"productName": "Laptop",
"quantity": 1,
"unitPrice": 1200.00
}
]
}'curl -X PATCH http://localhost:5000/api/orders/{order-id}/status \
-H "Content-Type: application/json" \
-d '"Confirmed"'Check the NotificationService logs to see event processing:
docker logs notificationservicecurl -X POST http://localhost:5002/api/ordersaga \
-H "Content-Type: application/json" \
-d '{
"userId": "{user-id-from-step-1}",
"totalAmount": 1500.00
}'Expected Flow:
- Order created in database
- Payment processed
- Inventory reserved
- Notification event saved to outbox
- Background processor publishes event
- Notification sent
If any step fails, compensation runs automatically:
- Refunds payment
- Releases inventory
- Deletes order
See SAGA-PATTERN.md for detailed testing scenarios.
Edit appsettings.json in each service:
{
"ConnectionStrings": {
"Redis": "localhost:6379"
},
"Redis": {
"InstanceName": "ServiceName_"
}
}{
"RabbitMQ": {
"Host": "localhost"
}
}{
"Authentication": {
"Authority": "http://localhost:5004"
},
"ClientCredentials": {
"Authority": "http://localhost:5004",
"ClientId": "service-client",
"ClientSecret": "your-secret"
}
}Customize in PollyPolicies.cs:
- Retry count and delay
- Circuit breaker thresholds
- Timeout duration
- Bulkhead limits
- User Service: http://localhost:5001/health
- Order Service: http://localhost:5002/health
- Notification Service: http://localhost:5003/health
- Identity Service: http://localhost:5004/.well-known/openid-configuration
Monitor queues and messages: http://localhost:15672
Access Jaeger UI: kubectl port-forward svc/jaeger 16686:16686 -n microservices
Access Prometheus: kubectl port-forward svc/prometheus 9090:9090 -n microservices
- .NET 10.0 - Latest .NET runtime
- ASP.NET Core - Web API framework
- Entity Framework Core - ORM with SQL Server
- IdentityServer (Duende) - Authentication/Authorization
- Redis - Distributed caching
- RabbitMQ - Message broker
- YARP - API Gateway (reverse proxy)
- Polly - Resilience and fault tolerance
- Docker - Containerization
- Kubernetes - Container orchestration
- Jaeger - Distributed tracing
- Prometheus - Metrics monitoring
- OpenTelemetry - Observability
- Separation of Concerns - Clear boundaries between services
- DRY Principle - Shared libraries for common functionality
- Fail-Fast - Circuit breakers prevent cascading failures
- Cache-Aside Pattern - Efficient caching with Redis
- Event-Driven Architecture - Loose coupling via message bus
- Health Checks - Monitoring and automatic recovery
- Zero-Trust Security - NetworkPolicies for network segmentation
- Container-First - Full Docker and Kubernetes support
Docker Compose:
docker-compose up --scale userservice=3 --scale orderservice=2Kubernetes (Automatic with HPA):
kubectl get hpa -n microservices| Service | Min Replicas | Max Replicas | CPU Target |
|---|---|---|---|
| API Gateway | 2 | 10 | 70% |
| User Service | 2 | 8 | 70% |
| Order Service | 2 | 8 | 70% |
| Notification Service | 2 | 6 | 70% |
| Identity Service | 2 | 6 | 70% |
- Kubernetes: K8s Services provide built-in load balancing
- Docker: Docker Compose DNS-based service discovery
Zero-trust NetworkPolicies control all pod-to-pod communication:
- Default deny all traffic
- Explicit allow rules for each service
- Infrastructure isolation (only specific services can access databases)
- Redis shared across all instances
- Cache invalidation coordinated via cache keys
- Check Docker containers:
docker ps -a - View service logs:
docker logs <container-name> - Verify infrastructure health: RabbitMQ Management UI
- Verify Redis connection:
docker logs redis - Check connection string in appsettings.json
- Test Redis:
docker exec -it redis redis-cli ping
- Check RabbitMQ: http://localhost:15672
- Verify NotificationService is running
- Check event handler registration in Program.cs
- Verify Identity Service is running: http://localhost:5004/.well-known/openid-configuration
- Check client credentials in appsettings.json
- Ensure JWT tokens are being passed in Authorization header
- Add API versioning
- Implement CQRS pattern
- Add centralized logging (Elasticsearch, Seq)
- Implement rate limiting at gateway level
- Add Pod Disruption Budgets for HA
- Implement Redis Sentinel/Cluster for HA
- Add RabbitMQ clustering
This project is provided as-is for educational and development purposes.
Feel free to submit issues and enhancement requests.