GeWuYou 317eddca9b docs(sidebar): 更新侧边栏导航结构并移除API参考页面
- 调整Core模块导航链接结构,从overview页面改为根路径
- 重构Core模块侧边栏,将原有的6个主要类别扩展为15个详细分类
- 精简Game模块侧边栏,保留场景管理和游戏设置两个主要功能
- 更新Godot集成模块侧边栏,新增协程、信号、存储等功能分类
- 修改源码生成器模块命名,将枚举扩展重命名为枚举生成器
- 新增抽象接口侧边栏,包含Core和Game抽象接口文档
- 调整教程模块顺序,新增入门教程和Godot集成教程分类
- 移除独立的API参考导航项,将其整合到相应模块中
- 修正生成器API文档链接路径错误问题
2026-02-11 12:52:14 +08:00

3.5 KiB
Raw Blame History

规则生成器

GFramework.SourceGenerators 自动生成规则验证代码

概述

规则生成器为实现了规则接口的类型自动生成验证方法。这使得规则定义更加简洁,并确保规则的一致性。

基本用法

定义规则

using GFramework.SourceGenerators.Attributes;

[RuleFor(typeof(Player))]
public class PlayerRule : IRule<Player>
{
    public RuleResult Validate(Player player)
    {
        if (player.Health <= 0)
        {
            return RuleResult.Invalid("玩家生命值不能为零或负数");
        }

        if (string.IsNullOrEmpty(player.Name))
        {
            return RuleResult.Invalid("玩家名称不能为空");
        }

        return RuleResult.Valid();
    }
}

使用生成的验证器

public class PlayerValidator
{
    // 自动生成 Validate 方法
    public void ValidatePlayer(Player player)
    {
        var result = PlayerRuleValidator.Validate(player);
        
        if (!result.IsValid)
        {
            Console.WriteLine($"验证失败: {result.ErrorMessage}");
        }
    }
}

组合规则

多规则组合

[RuleFor(typeof(Player), RuleCombinationType.And)]
public class PlayerHealthRule : IRule<Player>
{
    public RuleResult Validate(Player player)
    {
        if (player.Health <= 0)
            return RuleResult.Invalid("生命值必须大于0");
        return RuleResult.Valid();
    }
}

[RuleFor(typeof(Player), RuleCombinationType.And)]
public class PlayerNameRule : IRule<Player>
{
    public RuleResult Validate(Player player)
    {
        if (string.IsNullOrEmpty(player.Name))
            return RuleResult.Invalid("名称不能为空");
        return RuleResult.Valid();
    }
}

验证所有规则

public void ValidateAll(Player player)
{
    var results = PlayerRuleValidator.ValidateAll(player);
    
    foreach (var result in results)
    {
        if (!result.IsValid)
        {
            Console.WriteLine(result.ErrorMessage);
        }
    }
}

异步规则

[RuleFor(typeof(Player), IsAsync = true)]
public class AsyncPlayerRule : IAsyncRule<Player>
{
    public async Task<RuleResult> ValidateAsync(Player player)
    {
        // 异步验证,如检查服务器
        var isBanned = await CheckBanStatus(player.Id);
        
        if (isBanned)
        {
            return RuleResult.Invalid("玩家已被封禁");
        }
        
        return RuleResult.Valid();
    }
}

最佳实践

1. 单一职责

// 推荐:每个规则只验证一个方面
[RuleFor(typeof(Player))]
public class PlayerHealthRule : IRule<Player> { }

[RuleFor(typeof(Player))]
public class PlayerNameRule : IRule<Player> { }

// 避免:在一个规则中验证多个方面
[RuleFor(typeof(Player))]
public class PlayerMegaRule : IRule<Player>
{
    public RuleResult Validate(Player player)
    {
        // 验证健康、名称、等级...
        // 不要这样设计
    }
}

2. 清晰的错误信息

public RuleResult Validate(Player player)
{
    // 推荐:具体的错误信息
    return RuleResult.Invalid($"玩家 {player.Name} 的生命值 {player.Health} 不能小于 1");
    
    // 避免:模糊的错误信息
    return RuleResult.Invalid("无效的玩家");
}

相关文档