Spring Sample App
Overview
Spring is a full-stack event-sourced banking application built with the Mississippi framework. It demonstrates a core architectural principle: all business logic lives in one domain project (Spring.Domain), while the host applications (Spring.Runtime, Spring.Gateway, Spring.Client) contain only infrastructure wiring.
The sample models a banking domain with accounts, deposits, withdrawals, money transfers, and compliance flagging. Every feature is built using Mississippi's event-sourcing patterns - Commands, CommandHandlers, events, EventReducers, effects, sagas, and projections - all defined inside Spring.Domain.
What Spring Teaches
| Lesson | Where to Look |
|---|---|
Define an aggregate with Commands, CommandHandlers, events, and EventReducers | Building an Aggregate |
| Add side effects that react to events (sync and fire-and-forget) | Building an Aggregate - Effects |
| Orchestrate multi-step workflows with sagas and compensation | Building a Saga |
| Create read-optimized views from event streams | Building Projections |
| Keep hosts minimal with source-generated registration | Host Architecture |
Project Structure
Spring lives under samples/Spring/ and contains these projects:
| Project | Purpose | Host Surface |
|---|---|---|
Spring.Domain | Commands, CommandHandlers, events, EventReducers, effects, sagas, projections | Domain logic lives here |
Spring.Runtime | Orleans silo host - infrastructure wiring only | Compact Program.cs wiring |
Spring.Gateway | ASP.NET API host + Blazor static files | Compact Program.cs wiring |
Spring.Client | Blazor WebAssembly - UI shell and feature registration | Compact Program.cs wiring |
Spring.AppHost | .NET Aspire orchestration for local development | Configuration only |
Spring.Domain.L0Tests | Unit tests for domain logic | Test code |
Spring.L2Tests | Integration tests with real infrastructure | Test code |
The critical insight: Spring.Domain is a plain class library. It primarily references Mississippi abstractions, plus minimal framework/build dependencies (for example, Microsoft.Orleans.Sdk and Microsoft.Extensions.Http) - no web hosting stack or direct database client wiring.
The Domain-First Pattern
Mississippi enforces a strict separation:
| Concern | Where It Lives | Why |
|---|---|---|
| What business rules exist | Spring.Domain | Domain logic is the core asset |
| How commands are validated | Spring.Domain (CommandHandlers) | Business rules do not depend on infrastructure |
| What facts happened | Spring.Domain (events) | Events are the source of truth |
| How state changes | Spring.Domain (EventReducers) | Pure functions that apply events to state |
| What side effects run | Spring.Domain (effects) | Reactions to events, still domain-owned |
| How workflows coordinate | Spring.Domain (sagas) | Multi-step orchestration with compensation |
| What read models exist | Spring.Domain (projections) | Read-optimized views of event streams |
| How the system hosts | Spring.Runtime, Spring.Gateway, Spring.Client | Infrastructure wiring only |
This pattern means you can change hosting (swap Cosmos for PostgreSQL, replace SignalR with gRPC) without touching business logic. You can test all domain behavior in isolation with no infrastructure dependencies.
When learning Spring, start with the domain pages first (Aggregate → Saga → Projection). Host and client pages are implementation wiring details.
Learn More
- Key Concepts - Quick reference for the domain-modeling vocabulary used throughout Spring
- Host Architecture - How Runtime, Gateway, and Client stay minimal while the domain owns business logic
- Building an Aggregate - Step-by-step walkthrough of the BankAccount aggregate
- Building a Saga - Multi-step money transfer with compensation
- Building Projections - Read-optimized views from event streams
- Auth-Proof Mode - Verify generated HTTP and subscription authorization behavior locally
- MCP in VS Code - Connect VS Code to the Spring MCP endpoint for local tool testing