Getting Started with Orleans.StateMachineES

Welcome to Orleans.StateMachineES! This guide will help you get up and running with state machines in your Orleans applications.

What You'll Learn

This getting started series covers:

  1. Installation - Setting up Orleans.StateMachineES in your project
  2. First State Machine - Building your first state machine grain
  3. Core Concepts - Understanding states, triggers, and transitions
  4. Parameterized Triggers - Passing data with transitions
  5. Guard Conditions - Validating transitions with business logic
  6. Next Steps - Exploring advanced features

Prerequisites

Before you begin, ensure you have:

  • .NET 9.0 SDK or later installed
  • Basic Orleans knowledge - Understanding of grains and the Orleans runtime
  • C# familiarity - Knowledge of async/await, generics, and enums
  • An Orleans project - Either existing or newly created

If you're new to Orleans, check out the official Orleans documentation first.

Quick Overview

Orleans.StateMachineES provides state machine functionality for Orleans grains through:

Core Components

  • StateMachineGrain<TState, TTrigger> - Base class for state machine grains
  • EventSourcedStateMachineGrain<TState, TTrigger> - Event sourcing support
  • IStateMachineGrain<TState, TTrigger> - Standard grain interface

Key Features

  • Orleans-native async APIs
  • Compile-time safety with 10 Roslyn analyzers
  • Event sourcing with state replay
  • Production components (circuit breakers, retries)
  • Performance optimizations (TriggerParameterCache)

Learning Path

Beginner (Start Here)

  1. Install the packages
  2. Create your first state machine
  3. Understand core concepts

Intermediate

  1. Use parameterized triggers
  2. Add guard conditions
  3. Explore async patterns

Advanced

  1. Enable event sourcing
  2. Build hierarchical states
  3. Implement distributed sagas

Example: Order Processing

Here's a preview of what you'll be able to build:

public enum OrderState
{
    Draft,
    Submitted,
    PaymentPending,
    PaymentConfirmed,
    Processing,
    Shipped,
    Delivered,
    Cancelled
}

public enum OrderTrigger
{
    Submit,
    ConfirmPayment,
    Process,
    Ship,
    Deliver,
    Cancel
}

public class OrderGrain : StateMachineGrain<OrderState, OrderTrigger>, IOrderGrain
{
    protected override void BuildStateMachine()
    {
        StateMachine.Configure(OrderState.Draft)
            .Permit(OrderTrigger.Submit, OrderState.Submitted)
            .Permit(OrderTrigger.Cancel, OrderState.Cancelled);

        StateMachine.Configure(OrderState.Submitted)
            .OnEntry(() => StartPaymentProcessing())
            .Permit(OrderTrigger.ConfirmPayment, OrderState.PaymentConfirmed)
            .Permit(OrderTrigger.Cancel, OrderState.Cancelled);

        StateMachine.Configure(OrderState.PaymentConfirmed)
            .Permit(OrderTrigger.Process, OrderState.Processing);

        StateMachine.Configure(OrderState.Processing)
            .Permit(OrderTrigger.Ship, OrderState.Shipped);

        StateMachine.Configure(OrderState.Shipped)
            .Permit(OrderTrigger.Deliver, OrderState.Delivered);
    }

    private void StartPaymentProcessing()
    {
        // Payment gateway integration
        var paymentGrain = GrainFactory.GetGrain<IPaymentGrain>(this.GetPrimaryKeyLong());
        RegisterTimer(
            _ => paymentGrain.CheckPaymentStatusAsync(),
            null,
            TimeSpan.FromSeconds(30),
            TimeSpan.FromSeconds(30)
        );
    }
}

This state machine handles the complete order lifecycle with transitions, entry callbacks, and integration with other grains.

Need Help?

Ready to Begin?

Start with Installation →