SourceFlow.Net is an event-driven architecture framework implementing Command Query Responsibility Segregation (CQRS) and Event Sourcing patterns. The system separates command processing from event handling, enabling scalable and maintainable domain-driven design.
- Commands: Modify state through CommandBus
- Queries: Read from materialized views (ViewModels)
- Clear separation between write and read models
- Commands are persisted in CommandStore
- Events represent state changes
- Event replay capability for reconstructing state
- Long-running business processes
- Coordinate multiple commands across aggregates
- Handle complex workflows
┌─────────────────────────────────────────────────────────────┐
│ Client Application │
└───────────────────┬─────────────────────────────┬────────────┘
│ │
▼ ▼
┌──────────────────┐ ┌──────────────────┐
│ ICommandBus │ │ IEventQueue │
│ (Publish) │ │ (Enqueue) │
└────────┬─────────┘ └────────┬─────────┘
│ │
▼ ▼
┌──────────────────────┐ ┌──────────────────────┐
│ ICommandDispatcher[] │ │ IEventDispatcher[] │
└──────────┬───────────┘ └──────────┬───────────┘
│ │
▼ │
┌──────────────────────┐ │
│ ICommandSubscriber[] │ │
│ - CommandSubscriber│ │
│ (routes to Sagas)│ │
└──────────┬───────────┘ │
│ │
▼ ▼
┌───────────────┐ ┌─────────────────────┐
│ ISaga[] │ │ IEventSubscriber[] │
│ (Handles │ │ - Aggregate. │
│ Commands) │ │ EventSubscriber │
└───────┬───────┘ │ - Projections. │
│ │ EventSubscriber │
│ Publishes └──────────┬──────────┘
│ Events │
│ │
▼ ▼
┌───────────────┐ ┌─────────────────────┐
│ IEventQueue │ │ IAggregate[] │
│ │ │ IView[] │
└───────────────┘ │ (Subscribe/Project)│
└─────────────────────┘
- ICommandBus - Entry point for command publishing
- CommandBus - Manages command persistence and dispatching
- ICommandDispatcher - Routes commands to subscribers
- CommandDispatcher - Dispatches to all registered ICommandSubscriber instances
- ICommandSubscriber - Receives dispatched commands
- CommandSubscriber - Routes commands to appropriate Sagas
- ISaga - Handles commands and produces events
- IEventQueue - Entry point for event publishing
- EventQueue - Manages event distribution
- IEventDispatcher - Routes events to subscribers
- EventDispatcher - Dispatches to all registered IEventSubscriber instances
- IEventSubscriber - Receives dispatched events
- Aggregate.EventSubscriber - Routes to Aggregates implementing ISubscribes
- Projections.EventSubscriber - Routes to Views implementing IProjectOn
- ICommandStore - Interface for command persistence
- ICommandStoreAdapter - Scoped adapter wrapping ICommandStore
- Stores commands with sequence numbers for replay
- IEntityStore - Interface for entity persistence
- IEntityStoreAdapter - Scoped adapter wrapping IEntityStore
- Stores aggregate state
- IViewModelStore - Interface for read model persistence
- IViewModelStoreAdapter - Scoped adapter wrapping IViewModelStore
- Stores materialized views for queries
- IEventQueue - Thread-safe event distribution
- IEventDispatcher - Stateless event routing
- IEventSubscriber (both implementations) - Stateless subscription management
- IDomainTelemetryService - Observability and tracing
- ICommandBus - Per-request command handling
- ICommandDispatcher - Per-request command routing
- ICommandSubscriber - Per-request subscription handling
- ICommandPublisher - Per-request command publishing
- Store Adapters (ICommandStoreAdapter, IEntityStoreAdapter, IViewModelStoreAdapter)
- ISaga implementations
- IAggregate implementations
- IView implementations
Components are registered using the UseSourceFlow() extension method:
services.UseSourceFlow(ServiceLifetime.Singleton, assemblies);Key registration points (from IocExtensions.cs:33-98):
- Stores and adapters auto-discovered from assemblies
- Factories registered for aggregate creation
- Lazy to break circular dependencies
- Event/Command subscribers registered as Singleton/Scoped respectively
The framework includes built-in OpenTelemetry support:
- IDomainTelemetryService - Provides distributed tracing
- Traces command dispatching, event publishing, and replay operations
- Tags include: command/event type, entity IDs, sequence numbers, subscriber counts
Trace operations:
sourceflow.commandbus.dispatchsourceflow.commandbus.replaysourceflow.commanddispatcher.sendsourceflow.eventqueue.enqueuesourceflow.eventdispatcher.dispatch
- ArrayPool-based task collection optimization
- Used in CommandDispatcher and EventDispatcher
- Reduces allocations for parallel subscriber execution
- Separation of Concerns: Commands, Events, Aggregates, Sagas, and Views are distinct
- Interface-based Design: All major components use interfaces for extensibility
- Dependency Inversion: Components depend on abstractions, not implementations
- Single Responsibility: Each component has a focused purpose
- Open/Closed Principle: Extensible through new implementations without modifying core
All commands and events implement IMetadata:
- SequenceNo: Order of command/event
- IsReplay: Flag indicating replay vs. new command/event
- Used for event sourcing and replay scenarios
The architecture's interface-based design makes it suitable for cloud extension:
- New ICommandDispatcher implementation for AWS SQS
- New IEventDispatcher implementation for AWS SNS
- Selective routing based on command/event type
- Maintain existing local processing alongside cloud dispatch