Skip to main content

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

LessonWhere to Look
Define an aggregate with Commands, CommandHandlers, events, and EventReducersBuilding 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 compensationBuilding a Saga
Create read-optimized views from event streamsBuilding Projections
Keep hosts minimal with source-generated registrationHost Architecture

Project Structure

Spring lives under samples/Spring/ and contains these projects:

ProjectPurposeHost Surface
Spring.DomainCommands, CommandHandlers, events, EventReducers, effects, sagas, projectionsDomain logic lives here
Spring.RuntimeOrleans silo host - infrastructure wiring onlyCompact Program.cs wiring
Spring.GatewayASP.NET API host + Blazor static filesCompact Program.cs wiring
Spring.ClientBlazor WebAssembly - UI shell and feature registrationCompact Program.cs wiring
Spring.AppHost.NET Aspire orchestration for local developmentConfiguration only
Spring.Domain.L0TestsUnit tests for domain logicTest code
Spring.L2TestsIntegration tests with real infrastructureTest 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:

ConcernWhere It LivesWhy
What business rules existSpring.DomainDomain logic is the core asset
How commands are validatedSpring.Domain (CommandHandlers)Business rules do not depend on infrastructure
What facts happenedSpring.Domain (events)Events are the source of truth
How state changesSpring.Domain (EventReducers)Pure functions that apply events to state
What side effects runSpring.Domain (effects)Reactions to events, still domain-owned
How workflows coordinateSpring.Domain (sagas)Multi-step orchestration with compensation
What read models existSpring.Domain (projections)Read-optimized views of event streams
How the system hostsSpring.Runtime, Spring.Gateway, Spring.ClientInfrastructure 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 (AggregateSagaProjection). Host and client pages are implementation wiring details.

Learn More