Introduction
FullStackHero .NET Starter Kit is a modular monolith designed for building production-ready, multi-tenant applications. It combines the deployment simplicity of monoliths with the organizational benefits of microservices through well-defined module boundaries.Architecture Diagram
Core Architectural Principles
1. Modular Monolith
The application is structured as independent modules that communicate through well-defined contracts:- Identity Module: Authentication, authorization, users, roles, groups, sessions
- Multitenancy Module: Tenant management, provisioning, theme customization
- Auditing Module: Audit trail for HTTP requests and domain events
IModule interface:
2. Vertical Slice Architecture
Features are organized as self-contained vertical slices, not horizontal layers:- Command/Query: Request DTO implementing
ICommand<T>orIQuery<T> - Handler: Business logic implementing
ICommandHandlerorIQueryHandler - Validator: FluentValidation rules
- Endpoint: Minimal API endpoint mapping
3. CQRS with Mediator
Command Query Responsibility Segregation using the Mediator library (not MediatR):ValueTask<T> (not Task<T>) for better performance.
4. Domain-Driven Design
Rich domain models with encapsulated behavior:- Entities:
BaseEntity<TId>with domain events - Aggregates:
AggregateRoot<TId>for consistency boundaries - Value Objects: Immutable types for domain concepts
- Domain Events:
DomainEventfor cross-aggregate communication
BuildingBlocks/Core/Domain/.
5. Multi-Tenancy First
Built-in multi-tenancy using Finbuckle.MultiTenant:- Tenant Resolution: Header, claim, and query string strategies
- Data Isolation: Database-per-tenant pattern
- Distributed Cache: Cached tenant info for performance
- Tenant Context: Automatic tenant tracking on entities
Key Design Decisions
Minimal APIs
No controllers. All endpoints use Minimal API routing for better performance and simplicity.
Mediator (not MediatR)
Uses Mediator library with
ICommand/IQuery interfaces and ValueTask returns.Database Per Tenant
Each tenant gets its own database for maximum isolation and security.
Outbox Pattern
Transactional outbox ensures reliable event publishing with Hangfire.
Technology Stack
Module Communication
Modules communicate through:- Shared Contracts: Published DTOs and interfaces in
.Contractsprojects - Integration Events: Published to outbox, consumed asynchronously
- Direct Service Calls: For synchronous operations within bounded contexts
Modules must never reference other module implementations, only their contracts. This enforces loose coupling.
Building Blocks
The framework provides 11 building block packages:| Package | Purpose |
|---|---|
Core | Domain primitives, exceptions, context abstractions |
Persistence | DbContext base, repositories, interceptors |
Web | Module loader, middleware, exception handling |
Caching | Distributed and hybrid cache services |
Jobs | Hangfire integration for background tasks |
Mailing | Email templating and SMTP configuration |
Storage | File storage abstraction (local, cloud) |
Eventing | Domain events and outbox pattern |
Shared | Common constants and DTOs |
Blazor.UI | Blazor components and theming |
OpenAPI | Swagger/OpenAPI documentation |
Next Steps
Modular Monolith
Learn how modules are loaded and isolated
Vertical Slices
Understand the feature folder structure
CQRS & Mediator
Deep dive into commands, queries, and handlers
Domain-Driven Design
Explore entities, aggregates, and domain events
