A modern .NET modular monolith solution demonstrating enterprise messaging patterns, domain-driven design, and microservices communication using the Transponder messaging framework.
Sol9 is a comprehensive solution that showcases:
- Modular Monolith Architecture: Bookings and Orders modules with clear boundaries
- Enterprise Messaging: Transponder framework for reliable inter-module communication
- Multiple Transport Options: gRPC, SignalR, SSE, Webhooks, Kafka, RabbitMQ, AWS, Azure Service Bus
- Resilience Patterns: Outbox/inbox patterns, saga orchestration, message scheduling
- Modern .NET Stack: .NET 10, ASP.NET Core, Entity Framework Core, .NET Aspire
- Observability: OpenTelemetry, Serilog, structured logging
┌─────────────────────────────────────────────────────────────┐
│ Gateway.API (YARP) │
│ API Gateway & Reverse Proxy │
└──────────────┬──────────────────────────┬───────────────────┘
│ │
┌──────────▼──────────┐ ┌──────────▼──────────┐
│ Bookings.API │ │ Orders.API │
│ (gRPC + HTTP) │ │ (gRPC + HTTP) │
└──────────┬──────────┘ └──────────┬──────────┘
│ │
┌──────────▼──────────┐ ┌──────────▼──────────┐
│ Bookings.Application│ │ Orders.Application │
│ (Domain Logic) │ │ (Domain Logic) │
└──────────┬──────────┘ └──────────┬──────────┘
│ │
┌──────────▼──────────┐ ┌──────────▼──────────┐
│ Bookings.Infrastructure│ │ Orders.Infrastructure│
│ (EF Core + Repos) │ │ (EF Core + Repos) │
└──────────────────────┘ └──────────────────────┘
│ │
└──────────┬───────────────┘
│
┌───────────▼───────────┐
│ Transponder │
│ (Messaging Bus) │
└───────────┬───────────┘
│
┌─────────────────┼─────────────────┐
│ │ │
┌────▼────┐ ┌─────▼─────┐ ┌─────▼─────┐
│ gRPC │ │ SignalR │ │ Kafka │
│Transport│ │ Transport │ │Transport │
└─────────┘ └───────────┘ └──────────┘
- Transponder: Enterprise messaging framework with multiple transport support
- Intercessor: Mediator pattern implementation with pipeline behaviors
- Verifier: Validation framework with fluent rule builders
- Sol9.Core: Shared domain abstractions and integration events
- Sol9.Contracts: Shared message contracts for inter-module communication
- Bookings.API: Booking management service
- Orders.API: Order management service
- Gateway.API: YARP-based API gateway
- PostgreSQL: Primary database for Orders, Bookings, and Transponder persistence
- Redis: Caching and distributed coordination
- .NET Aspire: Application orchestration and observability
- .NET SDK 10.0.0 (see
global.json) - Docker Desktop (for Aspire containers and integration tests)
- PostgreSQL (optional, if not using Docker)
# Clone and restore
git clone <repository-url>
cd Sol9
dotnet restore
# Build solution
dotnet build Sol9.slnxdotnet run --project Sol9.AppHost/Sol9.AppHost.csprojThis starts:
- Bookings.API
- Orders.API
- Gateway.API
- PostgreSQL
- Redis
Access the Aspire dashboard at https://localhost:15000 to view service health, logs, and metrics.
# Bookings API
dotnet run --project Bookings.API/Bookings.API.csproj
# Orders API
dotnet run --project Orders.API/Orders.API.csproj
# Gateway API
dotnet run --project Gateway.API/Gateway.API.csprojDefault ports:
- Bookings.API:
http://localhost:5187/https://localhost:7266 - Orders.API:
http://localhost:5296/https://localhost:7268 - Gateway.API:
http://localhost:5400/https://localhost:7440
Comprehensive documentation is available in the docs/ directory:
- Transponder: Messaging framework – setup, config, when/where/why to use; transports (gRPC, Kafka, etc.)
- Intercessor: Mediator – commands, queries, notifications, pipeline behaviors; setup, config, when/where/why
- Verifier: Validation framework – fluent rules, sync/async validators; setup, config, when/where/why
- Deployment: Docker, Kubernetes, blue-green deployment, gRPC/Transponder configuration
- Documentation index: Overview of all docs and quick reference
Transponder supports multiple transport implementations:
- gRPC: High-performance RPC for service-to-service communication
- SignalR: Real-time bidirectional communication for web clients
- SSE: Server-Sent Events for one-way real-time updates
- Webhooks: HTTP-based webhook delivery
- Kafka: Distributed event streaming
- RabbitMQ: Message broker with advanced routing
- AWS SQS/SNS: Cloud messaging via AWS
- Azure Service Bus: Cloud messaging via Azure
See Transponder Transports Documentation for details.
- Request/Response: Synchronous communication between services
- Publish/Subscribe: Event-driven messaging
- Saga Orchestration: Distributed transaction coordination
- Outbox Pattern: Reliable message delivery with transactional guarantees
- Inbox Pattern: Idempotent message processing
- Message Scheduling: Delayed and scheduled message delivery
- Retry Policies: Configurable retry with exponential backoff
- Circuit Breakers: Automatic failure detection and recovery
- Dead-Letter Queues: Handling of unprocessable messages
- Optimistic Concurrency: Saga state versioning for conflict resolution
- Structured Logging: Serilog with correlation IDs
- Distributed Tracing: OpenTelemetry integration
- Metrics: Performance and health metrics
- Activity Scopes: Automatic context propagation
# Run all tests
dotnet test Sol9.slnx
# Run unit tests only
dotnet test Transponder.Tests/Transponder.Tests.csproj
# Run integration tests (requires Docker)
dotnet test Bookings.Integration.Tests/Bookings.Integration.Tests.csproj
dotnet test Orders.Integration.Tests/Orders.Integration.Tests.csproj
- Local: Rider "Run with Coverage" (dotCover) for fast feedback.
- Validation/CI: dotCover CLI (
dotnet dotCover cover ...). - Rider inspection: open
coverage/solution.dcvr(Coverage tool window). - CLI setup:
dotnet tool restore(installs dotCover tool). - Report output:
coverage/coverage.xml(XML report).
Configuration uses standard ASP.NET Core patterns:
- appsettings.json: Base configuration
- appsettings.{Environment}.json: Environment-specific overrides
- Environment Variables: Override any setting using
__separator
{
"ConnectionStrings": {
"Bookings": "Host=localhost;Database=bookings;Username=postgres;Password=postgres",
"Orders": "Host=localhost;Database=orders;Username=postgres;Password=postgres",
"Transponder": "Host=localhost;Database=transponder;Username=postgres;Password=postgres",
"Redis": "redis://localhost:6379"
},
"TransponderSettings": {
"LocalBaseAddress": "http://localhost:5187",
"RemoteBaseAddress": "http://localhost:5296"
}
}Sol9/
├── Bookings.API/ # Bookings web API
├── Bookings.Application/ # Bookings domain logic
├── Bookings.Domain/ # Bookings domain entities
├── Bookings.Infrastructure/ # Bookings data access
├── Orders.API/ # Orders web API
├── Orders.Application/ # Orders domain logic
├── Orders.Domain/ # Orders domain entities
├── Orders.Infrastructure/ # Orders data access
├── Gateway.API/ # API Gateway (YARP)
├── Transponder/ # Core messaging framework
├── Transponder.Transports.*/ # Transport implementations
├── Transponder.Persistence.*/ # Persistence implementations
├── Intercessor/ # Mediator library
├── Verifier/ # Validation library
├── Sol9.Contracts/ # Shared message contracts
├── Sol9.Core/ # Shared domain abstractions
├── Sol9.AppHost/ # Aspire orchestration
└── Sol9.ServiceDefaults/ # Service defaults
- Use Outbox Pattern: Always use outbox for cross-module messaging to ensure reliability
- Idempotent Handlers: Make message handlers idempotent to handle duplicates
- Shared Contracts: Keep message contracts in
Sol9.Contractsfor versioning - Structured Logging: Use correlation IDs for request tracing
- Validation: Validate all commands/queries using Verifier
- HTTPS for gRPC: Use HTTPS endpoints to enable HTTP/2
MIT License. See LICENSE file for details.
Contributions are welcome! Please ensure:
- Code follows existing patterns and conventions
- Tests are included for new features
- Documentation is updated
- All tests pass before submitting
For questions and issues, please open an issue in the repository.