Galosys.Foundation.Stateless 26.9.15.1

dotnet add package Galosys.Foundation.Stateless --version 26.9.15.1
                    
NuGet\Install-Package Galosys.Foundation.Stateless -Version 26.9.15.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Galosys.Foundation.Stateless" Version="26.9.15.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Galosys.Foundation.Stateless" Version="26.9.15.1" />
                    
Directory.Packages.props
<PackageReference Include="Galosys.Foundation.Stateless" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Galosys.Foundation.Stateless --version 26.9.15.1
                    
#r "nuget: Galosys.Foundation.Stateless, 26.9.15.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Galosys.Foundation.Stateless@26.9.15.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Galosys.Foundation.Stateless&version=26.9.15.1
                    
Install as a Cake Addin
#tool nuget:?package=Galosys.Foundation.Stateless&version=26.9.15.1
                    
Install as a Cake Tool

Galosys.Foundation.Stateless

基于 Stateless 库的状态机封装,实现 Core 模块的 IStateMachine<S, E, C> 接口,提供子状态(Substate)和动态目标(PermitDynamic)等高级特性。

成熟度: 🟢 生产可用 — 完整实现 Core 接口 + 15 个单元测试

安装

dotnet add package Galosys.Foundation.Stateless

最小配置

// 定义枚举
enum OrderState { Created, Paid, Delivered, Closed }
enum OrderTrigger { Pay, Deliver, Close }

// 注册状态机(在 Startup / Program.cs)
services.AddStatelessStateMachine<OrderState, OrderTrigger, object>(builder =>
{
    builder.ExternalTransition()
        .From(OrderState.Created).To(OrderState.Paid).On(OrderTrigger.Pay)
        .Perform((from, to, evt, ctx) => { /* 转换动作 */ });

    builder.ExternalTransition()
        .From(OrderState.Paid).To(OrderState.Delivered).On(OrderTrigger.Deliver)
        .Perform((from, to, evt, ctx) => { });

    builder.ExternalTransition()
        .From(OrderState.Created).To(OrderState.Closed).On(OrderTrigger.Close)
        .Perform((from, to, evt, ctx) => { });
}, "order-machine");

使用

// 注入工厂
IStateMachineFactory factory = ...;

// 获取状态机
var sm = factory.Get<OrderState, OrderTrigger, object>("order-machine");

// 触发转换
var result = await sm.FireAsync(OrderState.Created, OrderTrigger.Pay, null);
// result.Status == TransitionStatus.Accepted
// result.TargetState == OrderState.Paid

// 检查是否可触发
sm.CanFire(OrderState.Created, OrderTrigger.Pay); // true

// 获取允许的事件
var events = sm.GetPermittedEvents(OrderState.Created); // [Pay, Close]

与 Core 默认实现的区别

特性 Core 默认 (StateMachineImpl) Stateless 封装
基本转换
Guard 条件 ✅ Rejected 状态 ✅ NoTransition 状态
Internal 转换
拦截器/监听器
子状态 (Substate)
动态目标 (PermitDynamic)
PlantUML 生成 ✅ 自研 ✅ (DOT 格式)

子状态(Substate)

子状态继承父状态的转换规则:

services.AddStatelessStateMachine<OrderState, OrderTrigger, object>(builder =>
{
    // 父状态转换
    builder.ExternalTransition()
        .From(OrderState.Paid).To(OrderState.Delivered).On(OrderTrigger.Deliver)
        .Perform((from, to, evt, ctx) => { });

    // 子状态独立转换
    builder.ExternalTransition()
        .From(OrderState.Processing).To(OrderState.Suspended).On(OrderTrigger.Suspend)
        .Perform((from, to, evt, ctx) => { });

    // 声明子状态关系
    builder.AddSubstate(OrderState.Paid, OrderState.Processing);
}, "order-machine");

子状态 Processing 能响应父状态 PaidDeliver 事件,但 Paid 不会响应 ProcessingSuspend 事件。

动态目标(PermitDynamic)

根据上下文动态决定目标状态:

services.AddStatelessStateMachine<OrderState, OrderTrigger, OrderContext>(builder =>
{
    builder.AddDynamicTransition(
        OrderState.Created,
        OrderTrigger.Route,
        ctx => ctx.NeedsReview ? OrderState.Reviewing : OrderState.Approved);
}, "order-machine");

DI 覆盖策略

AddStatelessStateMachine 使用 AddSingleton<IStateMachineFactory> 覆盖 Core 的 TryAddSingleton 默认工厂。未引用 Stateless 模块的项目不受影响。

迁移指南(从旧 API)

旧 API(已删除)

// ❌ 已删除
public class OrderFsm : AbstractFsm<OrderState, OrderTrigger>
{
    protected override void ConfigureStateMachine() { ... }
}

services.AddStateless();
var fsm = sp.GetRequiredService<OrderFsm>();
fsm.Init(OrderState.Created);
await fsm.FireAsync("order-123", OrderTrigger.Pay);

新 API

// ✅ 新 API
services.AddStatelessStateMachine<OrderState, OrderTrigger, object>(builder =>
{
    builder.ExternalTransition()
        .From(OrderState.Created).To(OrderState.Paid).On(OrderTrigger.Pay)
        .Perform((from, to, evt, ctx) => { });
}, "order-machine");

var sm = factory.Get<OrderState, OrderTrigger, object>("order-machine");
var result = await sm.FireAsync(OrderState.Created, OrderTrigger.Pay, null);

关键变更:

  • AbstractFsm<S, E> 继承 → IStateMachine<S, E, C> 接口
  • Init(state) → 无需初始化(无状态设计,状态通过参数传入)
  • FireAsync(resourceId, trigger)FireAsync(sourceState, event, context)
  • services.AddStateless()services.AddStatelessStateMachine<S, E, C>(...)
Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
26.9.15.1 0 9/15/2026
26.9.14.1 0 9/15/2026
26.8.29.1 84 8/31/2026
26.8.26.1 82 8/26/2026
26.8.23.1 94 8/23/2026
26.8.21.1 90 8/21/2026
26.8.20.1 90 8/20/2026
26.8.18.1 90 8/18/2026
26.8.17.1 95 8/17/2026
26.8.13.2 93 8/13/2026
26.8.13.1 93 8/13/2026
26.8.12.2 88 8/12/2026
26.8.12.1 89 8/12/2026
26.8.10.1 90 8/10/2026
26.8.5.1 89 8/5/2026
26.8.4.1 107 8/4/2026
26.8.3.1 99 8/3/2026
26.7.31.1 102 7/31/2026
26.7.30.1 95 7/30/2026
26.7.29.1 103 7/29/2026
Loading failed