feat(config): 添加YAML配置文件的JSON Schema校验功能#211
Conversation
- 实现了YAML配置与JSON Schema的运行时校验能力 - 支持嵌套对象、对象数组、标量数组的递归校验 - 提供async和sync两种模式的schema文件加载解析 - 实现跨表引用的收集与校验机制 - 支持enum枚举值、引用约束和深层约束校验 - 添加了multipleOf、uniqueItems、contains等高级校验功能 - 实现了minProperties、maxProperties对象属性数量校验 - 提供详细的错误诊断信息和路径定位功能
Reviewer's Guide添加可复用的 YAML 文本验证与序列化工具,并将其接入生成的配置绑定中,基于 JSON Schema 为 YAML 配置提供同步/异步验证及相关路径辅助方法,同时重构 Schema 加载逻辑以支持同步与异步两种流程,并扩展这些行为的测试覆盖率。 通过生成绑定进行 YAML 验证的时序图sequenceDiagram
actor Host
participant MonsterConfigBindings
participant YamlConfigTextValidator
participant YamlConfigSchemaValidator
participant FileSystem
participant YamlConfigSchema
Host->>MonsterConfigBindings: ValidateYaml(configRootPath, yamlPath, yamlText)
MonsterConfigBindings->>MonsterConfigBindings: GetSchemaPath(configRootPath)
MonsterConfigBindings->>YamlConfigTextValidator: Validate(Metadata.TableName, schemaPath, yamlPath, yamlText)
YamlConfigTextValidator->>YamlConfigSchemaValidator: Load(tableName, schemaPath)
YamlConfigSchemaValidator->>FileSystem: File.Exists(schemaPath)
alt schemaFileMissing
YamlConfigSchemaValidator-->>YamlConfigTextValidator: throw ConfigLoadException(SchemaFileNotFound)
YamlConfigTextValidator-->>MonsterConfigBindings: exception
MonsterConfigBindings-->>Host: exception
else schemaFileExists
YamlConfigSchemaValidator->>FileSystem: File.ReadAllText(schemaPath)
YamlConfigSchemaValidator->>YamlConfigSchemaValidator: ParseLoadedSchema(tableName, schemaPath, schemaText)
YamlConfigSchemaValidator-->>YamlConfigTextValidator: YamlConfigSchema
YamlConfigTextValidator->>YamlConfigSchemaValidator: Validate(tableName, schema, yamlPath, yamlText)
alt yamlInvalid
YamlConfigSchemaValidator-->>YamlConfigTextValidator: throw ConfigLoadException(FailureKind)
YamlConfigTextValidator-->>MonsterConfigBindings: exception
MonsterConfigBindings-->>Host: exception
else yamlValid
YamlConfigSchemaValidator-->>YamlConfigTextValidator: success
YamlConfigTextValidator-->>MonsterConfigBindings: return
MonsterConfigBindings-->>Host: return
end
end
rect rgb(235, 235, 255)
note over Host,YamlConfigSchemaValidator: Async variant
Host->>MonsterConfigBindings: ValidateYamlAsync(configRootPath, yamlPath, yamlText, cancellationToken)
MonsterConfigBindings->>YamlConfigTextValidator: ValidateAsync(tableName, schemaPath, yamlPath, yamlText, cancellationToken)
YamlConfigTextValidator->>YamlConfigSchemaValidator: LoadAsync(tableName, schemaPath, cancellationToken)
YamlConfigSchemaValidator-->>YamlConfigTextValidator: YamlConfigSchema
YamlConfigTextValidator->>YamlConfigSchemaValidator: Validate(tableName, schema, yamlPath, yamlText)
YamlConfigSchemaValidator-->>YamlConfigTextValidator: success or ConfigLoadException
YamlConfigTextValidator-->>MonsterConfigBindings: Task
MonsterConfigBindings-->>Host: Task
end
YAML 文本序列化与验证辅助类类图classDiagram
class MonsterConfigBindings {
+const string SchemaRelativePath
+const string ConfigRelativePath
+static string SerializeToYaml(MonsterConfig config)
+static string GetConfigDirectoryPath(string configRootPath)
+static string GetSchemaPath(string configRootPath)
+static void ValidateYaml(string configRootPath, string yamlPath, string yamlText)
+static System.Threading.Tasks.Task ValidateYamlAsync(string configRootPath, string yamlPath, string yamlText, System.Threading.CancellationToken cancellationToken)
-static string ResolveAbsolutePath(string configRootPath, string relativePath)
}
class MonsterConfig {
+int Id
+string Name
+int Hp
+string Faction
}
class YamlConfigTextSerializer {
-static ISerializer Serializer
+static string Serialize~TValue~(TValue value)
}
class YamlConfigTextValidator {
+static void Validate(string tableName, string schemaPath, string yamlPath, string yamlText)
+static System.Threading.Tasks.Task ValidateAsync(string tableName, string schemaPath, string yamlPath, string yamlText, System.Threading.CancellationToken cancellationToken)
}
class YamlConfigSchemaValidator {
+static System.Threading.Tasks.Task~YamlConfigSchema~ LoadAsync(string tableName, string schemaPath, System.Threading.CancellationToken cancellationToken)
+static YamlConfigSchema Load(string tableName, string schemaPath)
+static void Validate(string tableName, YamlConfigSchema schema, string yamlPath, string yamlText)
-static YamlConfigSchema ParseLoadedSchema(string tableName, string schemaPath, string schemaText)
}
class YamlConfigSchema {
+string SchemaPath
+YamlConfigSchemaNode RootNode
+string[] ReferencedTableNames
}
class YamlConfigSchemaNode {
+YamlConfigSchemaPropertyType NodeType
+string SchemaPathHint
+static YamlConfigSchemaNode CreateObject(System.Collections.Generic.IReadOnlyDictionary~string,YamlConfigSchemaNode~ properties, System.Collections.Generic.IReadOnlyCollection~string~ requiredProperties, YamlConfigObjectConstraints objectConstraints, string schemaPathHint)
+static YamlConfigSchemaNode CreateArray(YamlConfigSchemaNode itemNode, YamlConfigArrayConstraints arrayConstraints, string schemaPathHint)
+static YamlConfigSchemaNode CreateScalar(YamlConfigSchemaPropertyType nodeType, string referenceTableName, System.Collections.Generic.IReadOnlyCollection~string~ allowedValues, YamlConfigScalarConstraints constraints, string schemaPathHint)
}
class YamlConfigObjectConstraints
class YamlConfigArrayConstraints
class YamlConfigScalarConstraints
class YamlConfigSchemaPropertyType
class ConfigLoadException {
+ConfigLoadDiagnostic Diagnostic
}
class ConfigLoadDiagnostic {
+string TableName
+string SchemaPath
+string YamlPath
+ConfigLoadFailureKind FailureKind
}
class ConfigLoadFailureKind
MonsterConfigBindings ..> MonsterConfig : uses
MonsterConfigBindings ..> YamlConfigTextSerializer : calls
MonsterConfigBindings ..> YamlConfigTextValidator : calls
YamlConfigTextValidator ..> YamlConfigSchemaValidator : calls
YamlConfigSchemaValidator --> YamlConfigSchema : creates
YamlConfigSchema --> YamlConfigSchemaNode : rootNode
YamlConfigSchemaNode ..> YamlConfigObjectConstraints : uses
YamlConfigSchemaNode ..> YamlConfigArrayConstraints : uses
YamlConfigSchemaNode ..> YamlConfigScalarConstraints : uses
YamlConfigSchemaNode ..> YamlConfigSchemaPropertyType : uses
YamlConfigSchemaValidator ..> ConfigLoadException : throws
ConfigLoadException --> ConfigLoadDiagnostic : has
ConfigLoadDiagnostic ..> ConfigLoadFailureKind : uses
YamlConfigTextSerializer ..> ISerializer : uses
YamlConfigTextSerializer ..> CamelCaseNamingConvention : uses
YamlConfigTextSerializer ..> DefaultValuesHandling : uses
文件级变更
Tips and commandsInteracting with Sourcery
Customizing Your Experience访问你的 dashboard 可以:
Getting HelpOriginal review guide in EnglishReviewer's GuideAdds reusable YAML text validation and serialization utilities wired into generated config bindings, exposing sync/async JSON Schema-based validation for YAML configs and associated path helpers, while refactoring schema loading to support both async and sync flows and expanding test coverage for these behaviors. Sequence diagram for YAML validation via generated bindingssequenceDiagram
actor Host
participant MonsterConfigBindings
participant YamlConfigTextValidator
participant YamlConfigSchemaValidator
participant FileSystem
participant YamlConfigSchema
Host->>MonsterConfigBindings: ValidateYaml(configRootPath, yamlPath, yamlText)
MonsterConfigBindings->>MonsterConfigBindings: GetSchemaPath(configRootPath)
MonsterConfigBindings->>YamlConfigTextValidator: Validate(Metadata.TableName, schemaPath, yamlPath, yamlText)
YamlConfigTextValidator->>YamlConfigSchemaValidator: Load(tableName, schemaPath)
YamlConfigSchemaValidator->>FileSystem: File.Exists(schemaPath)
alt schemaFileMissing
YamlConfigSchemaValidator-->>YamlConfigTextValidator: throw ConfigLoadException(SchemaFileNotFound)
YamlConfigTextValidator-->>MonsterConfigBindings: exception
MonsterConfigBindings-->>Host: exception
else schemaFileExists
YamlConfigSchemaValidator->>FileSystem: File.ReadAllText(schemaPath)
YamlConfigSchemaValidator->>YamlConfigSchemaValidator: ParseLoadedSchema(tableName, schemaPath, schemaText)
YamlConfigSchemaValidator-->>YamlConfigTextValidator: YamlConfigSchema
YamlConfigTextValidator->>YamlConfigSchemaValidator: Validate(tableName, schema, yamlPath, yamlText)
alt yamlInvalid
YamlConfigSchemaValidator-->>YamlConfigTextValidator: throw ConfigLoadException(FailureKind)
YamlConfigTextValidator-->>MonsterConfigBindings: exception
MonsterConfigBindings-->>Host: exception
else yamlValid
YamlConfigSchemaValidator-->>YamlConfigTextValidator: success
YamlConfigTextValidator-->>MonsterConfigBindings: return
MonsterConfigBindings-->>Host: return
end
end
rect rgb(235, 235, 255)
note over Host,YamlConfigSchemaValidator: Async variant
Host->>MonsterConfigBindings: ValidateYamlAsync(configRootPath, yamlPath, yamlText, cancellationToken)
MonsterConfigBindings->>YamlConfigTextValidator: ValidateAsync(tableName, schemaPath, yamlPath, yamlText, cancellationToken)
YamlConfigTextValidator->>YamlConfigSchemaValidator: LoadAsync(tableName, schemaPath, cancellationToken)
YamlConfigSchemaValidator-->>YamlConfigTextValidator: YamlConfigSchema
YamlConfigTextValidator->>YamlConfigSchemaValidator: Validate(tableName, schema, yamlPath, yamlText)
YamlConfigSchemaValidator-->>YamlConfigTextValidator: success or ConfigLoadException
YamlConfigTextValidator-->>MonsterConfigBindings: Task
MonsterConfigBindings-->>Host: Task
end
Class diagram for YAML text serialization and validation helpersclassDiagram
class MonsterConfigBindings {
+const string SchemaRelativePath
+const string ConfigRelativePath
+static string SerializeToYaml(MonsterConfig config)
+static string GetConfigDirectoryPath(string configRootPath)
+static string GetSchemaPath(string configRootPath)
+static void ValidateYaml(string configRootPath, string yamlPath, string yamlText)
+static System.Threading.Tasks.Task ValidateYamlAsync(string configRootPath, string yamlPath, string yamlText, System.Threading.CancellationToken cancellationToken)
-static string ResolveAbsolutePath(string configRootPath, string relativePath)
}
class MonsterConfig {
+int Id
+string Name
+int Hp
+string Faction
}
class YamlConfigTextSerializer {
-static ISerializer Serializer
+static string Serialize~TValue~(TValue value)
}
class YamlConfigTextValidator {
+static void Validate(string tableName, string schemaPath, string yamlPath, string yamlText)
+static System.Threading.Tasks.Task ValidateAsync(string tableName, string schemaPath, string yamlPath, string yamlText, System.Threading.CancellationToken cancellationToken)
}
class YamlConfigSchemaValidator {
+static System.Threading.Tasks.Task~YamlConfigSchema~ LoadAsync(string tableName, string schemaPath, System.Threading.CancellationToken cancellationToken)
+static YamlConfigSchema Load(string tableName, string schemaPath)
+static void Validate(string tableName, YamlConfigSchema schema, string yamlPath, string yamlText)
-static YamlConfigSchema ParseLoadedSchema(string tableName, string schemaPath, string schemaText)
}
class YamlConfigSchema {
+string SchemaPath
+YamlConfigSchemaNode RootNode
+string[] ReferencedTableNames
}
class YamlConfigSchemaNode {
+YamlConfigSchemaPropertyType NodeType
+string SchemaPathHint
+static YamlConfigSchemaNode CreateObject(System.Collections.Generic.IReadOnlyDictionary~string,YamlConfigSchemaNode~ properties, System.Collections.Generic.IReadOnlyCollection~string~ requiredProperties, YamlConfigObjectConstraints objectConstraints, string schemaPathHint)
+static YamlConfigSchemaNode CreateArray(YamlConfigSchemaNode itemNode, YamlConfigArrayConstraints arrayConstraints, string schemaPathHint)
+static YamlConfigSchemaNode CreateScalar(YamlConfigSchemaPropertyType nodeType, string referenceTableName, System.Collections.Generic.IReadOnlyCollection~string~ allowedValues, YamlConfigScalarConstraints constraints, string schemaPathHint)
}
class YamlConfigObjectConstraints
class YamlConfigArrayConstraints
class YamlConfigScalarConstraints
class YamlConfigSchemaPropertyType
class ConfigLoadException {
+ConfigLoadDiagnostic Diagnostic
}
class ConfigLoadDiagnostic {
+string TableName
+string SchemaPath
+string YamlPath
+ConfigLoadFailureKind FailureKind
}
class ConfigLoadFailureKind
MonsterConfigBindings ..> MonsterConfig : uses
MonsterConfigBindings ..> YamlConfigTextSerializer : calls
MonsterConfigBindings ..> YamlConfigTextValidator : calls
YamlConfigTextValidator ..> YamlConfigSchemaValidator : calls
YamlConfigSchemaValidator --> YamlConfigSchema : creates
YamlConfigSchema --> YamlConfigSchemaNode : rootNode
YamlConfigSchemaNode ..> YamlConfigObjectConstraints : uses
YamlConfigSchemaNode ..> YamlConfigArrayConstraints : uses
YamlConfigSchemaNode ..> YamlConfigScalarConstraints : uses
YamlConfigSchemaNode ..> YamlConfigSchemaPropertyType : uses
YamlConfigSchemaValidator ..> ConfigLoadException : throws
ConfigLoadException --> ConfigLoadDiagnostic : has
ConfigLoadDiagnostic ..> ConfigLoadFailureKind : uses
YamlConfigTextSerializer ..> ISerializer : uses
YamlConfigTextSerializer ..> CamelCaseNamingConvention : uses
YamlConfigTextSerializer ..> DefaultValuesHandling : uses
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthrough新增基于文本的 YAML 序列化与验证 API;引入同步/异步 schema 加载并抽取解析逻辑以保证引用表名的确定性排序;源生成器为每个生成的 ConfigBindings 添加 YAML 序列化/路径/验证辅助方法;新增多项单元与集成测试覆盖新行为与诊断。 Changes
Sequence Diagram(s)sequenceDiagram
participant Test as 测试/调用者
participant Generated as 生成的 Bindings
participant Serializer as YamlConfigTextSerializer
participant YamlLib as Yaml 库
Test->>Generated: SerializeToYaml(config)
Generated->>Serializer: Serialize<T>(config)
Serializer->>YamlLib: 调用序列化(配置 CamelCase、禁用别名)
YamlLib-->>Serializer: 返回 YAML 文本
Serializer->>Serializer: 确保尾部有 "\n"
Serializer-->>Generated: 返回 YAML 文本
Generated-->>Test: 返回 YAML 文本
sequenceDiagram
participant Test as 测试/调用者
participant Generated as 生成的 Bindings
participant TextValidator as YamlConfigTextValidator
participant SchemaValidator as YamlConfigSchemaValidator
participant FileSystem as 文件系统
participant Parser as JSON 解析器
Test->>Generated: ValidateYaml(configRoot, yamlPath, yamlText)
Generated->>Generated: ResolveAbsolutePath(configRoot, relativeSchemaPath)
Generated->>TextValidator: Validate(tableName, schemaPath, yamlPath, yamlText)
TextValidator->>SchemaValidator: Load/LoadAsync(tableName, schemaPath)
SchemaValidator->>FileSystem: 读取 schema 文件
FileSystem-->>SchemaValidator: 返回 schema JSON 文本
SchemaValidator->>Parser: 解析 JSON 并收集引用表名(并排序)
Parser-->>SchemaValidator: 返回 YamlConfigSchema
SchemaValidator-->>TextValidator: 返回 Schema
TextValidator->>SchemaValidator: 验证 YAML 文本(或抛出 ConfigLoadException 包含 Diagnostic)
SchemaValidator-->>TextValidator: 验证结果或异常
TextValidator-->>Generated: 验证完成或抛出
Generated-->>Test: 验证结果或异常
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Hey - 我发现了 1 个问题,并留下了一些整体性的反馈:
- YamlConfigTextValidator.Validate/ValidateAsync 在每次调用时都会加载并解析 schema 文件;如果这些辅助方法会在高频保存路径中被调用,建议考虑提供一个接受预加载好的 YamlConfigSchema 的重载,或者增加一个简单的缓存层,以避免对相同的表/Schema 路径进行重复的磁盘 IO 和 JSON 解析。
给 AI Agent 的提示词
Please address the comments from this code review:
## Overall Comments
- YamlConfigTextValidator.Validate/ValidateAsync load and parse the schema file on every call; if these helpers are used on hot save paths, consider exposing an overload that accepts a preloaded YamlConfigSchema or adding a simple caching layer to avoid repeated disk IO and JSON parsing for the same table/schema path.
## Individual Comments
### Comment 1
<location path="GFramework.Game/Config/YamlConfigTextSerializer.cs" line_range="8-12" />
<code_context>
+/// </summary>
+public static class YamlConfigTextSerializer
+{
+ private static readonly ISerializer Serializer = new SerializerBuilder()
+ .WithNamingConvention(CamelCaseNamingConvention.Instance)
+ .DisableAliases()
+ .ConfigureDefaultValuesHandling(DefaultValuesHandling.Preserve)
+ .Build();
+
+ /// <summary>
</code_context>
<issue_to_address>
**question (bug_risk):** 请澄清或验证共享 `Serializer` 实例在被多个调用方使用时的线程安全假设。
静态的 `Serializer` 实例会被所有调用 `Serialize` 的代码共享,包括来自多个线程的调用。这依赖于 `YamlDotNet` 的 `ISerializer` 对并发使用是安全的。
如果这一点没有被明确保证,要么在这里文档化该线程安全前提,要么改为每次调用(或使用对象池)创建独立的 serializer,以避免在这个共享辅助方法中出现隐蔽的并发问题。
</issue_to_address>帮我变得更有用!请在每条评论上点击 👍 或 👎,我会根据你的反馈改进后续的审查。
Original comment in English
Hey - I've found 1 issue, and left some high level feedback:
- YamlConfigTextValidator.Validate/ValidateAsync load and parse the schema file on every call; if these helpers are used on hot save paths, consider exposing an overload that accepts a preloaded YamlConfigSchema or adding a simple caching layer to avoid repeated disk IO and JSON parsing for the same table/schema path.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- YamlConfigTextValidator.Validate/ValidateAsync load and parse the schema file on every call; if these helpers are used on hot save paths, consider exposing an overload that accepts a preloaded YamlConfigSchema or adding a simple caching layer to avoid repeated disk IO and JSON parsing for the same table/schema path.
## Individual Comments
### Comment 1
<location path="GFramework.Game/Config/YamlConfigTextSerializer.cs" line_range="8-12" />
<code_context>
+/// </summary>
+public static class YamlConfigTextSerializer
+{
+ private static readonly ISerializer Serializer = new SerializerBuilder()
+ .WithNamingConvention(CamelCaseNamingConvention.Instance)
+ .DisableAliases()
+ .ConfigureDefaultValuesHandling(DefaultValuesHandling.Preserve)
+ .Build();
+
+ /// <summary>
</code_context>
<issue_to_address>
**question (bug_risk):** Clarify or verify thread-safety assumptions of the shared `Serializer` instance used from multiple callers.
The static `Serializer` instance will be shared by all callers of `Serialize`, including from multiple threads. This relies on `YamlDotNet`’s `ISerializer` being safe for concurrent use.
If that’s not explicitly guaranteed, either document the thread-safety requirement here or switch to per-call (or pooled) serializers to avoid subtle concurrency issues in this shared helper.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
- 集成YamlDotNet库实现YAML配置文件的序列化功能 - 在配置消费者集成测试中添加抽象配置接口引用 - 在YAML配置验证测试中添加抽象配置接口引用 - 统一配置模块的依赖注入和接口抽象层次
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs`:
- Around line 271-289: The async validation test only asserts the success path
for MonsterConfigBindings.ValidateYamlAsync but lacks a failing-branch
assertion; add an Assert.ThrowsAsync<ConfigLoadException> call that invokes
MonsterConfigBindings.ValidateYamlAsync(_rootPath, "monster/generated.yaml",
invalidYaml) (using the existing invalidYaml) and assert the thrown exception's
Diagnostic.SchemaPath and Diagnostic.FailureKind match the same expectations
used for the synchronous test (SchemaPath equals schemaPath and FailureKind
equals ConfigLoadFailureKind.UnknownProperty) to cover the async failure branch.
In `@GFramework.Game/Config/YamlConfigSchemaValidator.cs`:
- Around line 268-271: The current code builds referencedTableNames as a
HashSet<string> in CollectReferencedTableNames and passes
referencedTableNames.ToArray() into the YamlConfigSchema ctor, producing an
unstable iteration order; before creating the YamlConfigSchema, convert the set
to a stable ordered sequence (e.g., sort the entries using
StringComparer.Ordinal) and pass that sorted array to the YamlConfigSchema
constructor so the exported referenced table list is deterministic.
In `@GFramework.Game/Config/YamlConfigTextSerializer.cs`:
- Around line 14-20: 为公开方法 Serialize<TValue> 补充 XML 文档中的 <exception>
标签,明确说明该方法在何种情况下会抛出 ArgumentNullException(例如当传入的 value 为 null 或方法内部依赖的必需参数为 null
时),并在异常说明中给出简短的上下文(“当 value 为 null 时抛出”),将该 <exception> 元素添加到现有的
<summary>/<typeparam>/<param>/<returns> 注释中以满足文档要求。
In `@GFramework.Game/Config/YamlConfigTextValidator.cs`:
- Around line 8-43: Add full XML documentation to the public methods Validate
and ValidateAsync: include <summary> (existing), <param> entries for tableName,
schemaPath, yamlPath, yamlText and cancellationToken (for ValidateAsync), a
<returns> describing that ValidateAsync returns a Task that completes when
validation finishes, and <exception> tags listing the specific exceptions these
methods may throw (e.g. ArgumentNullException/ArgumentException for invalid
params, ConfigLoadException from YamlConfigSchemaValidator.Load/LoadAsync, and
OperationCanceledException for ValidateAsync when cancellationToken is
triggered). Also add a brief <remarks> note about synchronous vs asynchronous
behavior and mention that Validate delegates to
YamlConfigSchemaValidator.Validate and ValidateAsync calls LoadAsync before
validation.
In `@GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs`:
- Around line 1687-1765: 生成的 YAML helper 注释缺少 <exception> 标签:Update
AppendYamlSerializationHelpers so the generated docs for GetConfigDirectoryPath,
GetSchemaPath, ValidateYaml and ValidateYamlAsync include appropriate
<exception> entries (e.g. ArgumentNullException / ArgumentException for
invalid/null configRootPath and ArgumentNullException for null yamlText/yamlPath
where applicable). Locate AppendYamlSerializationHelpers in
SchemaConfigGenerator.cs and add builder.AppendLine(...) calls to emit
<exception> XML for each method (matching the runtime throws) directly beneath
the corresponding <param> blocks so the generated API docs reflect the actual
contract for GetConfigDirectoryPath, GetSchemaPath, ValidateYaml and
ValidateYamlAsync.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 61000ea9-1e64-4a30-a6f4-8f0e1d12559e
📒 Files selected for processing (8)
GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.csGFramework.Game.Tests/Config/YamlConfigTextValidatorTests.csGFramework.Game/Config/YamlConfigSchemaValidator.csGFramework.Game/Config/YamlConfigTextSerializer.csGFramework.Game/Config/YamlConfigTextValidator.csGFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.csGFramework.SourceGenerators.Tests/Config/snapshots/SchemaConfigGenerator/MonsterConfigBindings.g.txtGFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Code Quality & Security
- GitHub Check: Analyze (C#)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.cs
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.cs: LoggerGenerator must automatically generate log fields and logging helper methods for classes decorated with [Log] attribute
PriorityGenerator must generate priority comparison implementations for classes decorated with [Priority] attribute
EnumExtensionsGenerator must generate enum extension capabilities for enums decorated with [GenerateEnumExtensions] attribute
ContextAwareGenerator must automatically implement IContextAware boilerplate logic for classes decorated with [ContextAware] attribute
**/*.cs: All public, protected, and internal types and members MUST include XML documentation comments (///) with<summary>,<param>,<returns>,<exception>, and<remarks>tags where applicable
XML documentation comments must explain intent, contract, and usage constraints instead of restating syntax
Add inline comments for non-trivial logic, concurrency/threading behavior, performance-sensitive paths, workarounds, compatibility constraints, edge cases, registration order, lifecycle sequencing, and generated code assumptions
Core framework components (Architecture, Module, System, Context, Registry, Service Module, Lifecycle types) MUST include high-level explanations of responsibilities, lifecycle, interactions with other components, why the abstraction exists, and when to use it instead of alternatives
Generated logic and source generator pipelines MUST explain what is generated, why it is generated, semantic assumptions the generator relies on, and any diagnostics or fallback behavior
Methods with non-trivial logic MUST document the core idea, key decisions, and edge case handling
Do not rely on implicit imports; declare every requiredusingexplicitly
Write null-safe code that respects nullable annotations instead of suppressing warnings by default
Use namespace patternGFramework.{Module}.{Feature}with PascalCase segments
Follow standard C# naming: Types/methods/properties/events/constants use PascalCase, interfaces useIprefix, parame...
Files:
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.csGFramework.Game/Config/YamlConfigTextSerializer.csGFramework.Game/Config/YamlConfigTextValidator.csGFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.csGFramework.SourceGenerators/Config/SchemaConfigGenerator.csGFramework.Game.Tests/Config/YamlConfigTextValidatorTests.csGFramework.Game/Config/YamlConfigSchemaValidator.cs
🧠 Learnings (11)
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.Tests.cs : Source generator changes MUST be covered by generator tests
Applied to files:
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.csGFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.csGFramework.SourceGenerators/Config/SchemaConfigGenerator.csGFramework.Game.Tests/Config/YamlConfigTextValidatorTests.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.Tests.cs : Preserve snapshot-based verification patterns already used in the repository for source generator tests
Applied to files:
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.csGFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.csGFramework.Game.Tests/Config/YamlConfigTextValidatorTests.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.Tests.cs : Public API changes must be covered by unit or integration tests
Applied to files:
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.csGFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.csGFramework.Game.Tests/Config/YamlConfigTextValidatorTests.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.Tests.cs : Regression fixes should include a test that fails before the fix and passes after it
Applied to files:
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.csGFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.csGFramework.Game.Tests/Config/YamlConfigTextValidatorTests.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.cs : When generator behavior changes intentionally, update snapshots together with the implementation
Applied to files:
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.csGFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.Tests.cs : Keep tests focused on observable behavior, not implementation trivia
Applied to files:
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.csGFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.Tests.cs : When a public API defines multiple contract branches, tests MUST cover the meaningful variants including null, empty, default, and filtered inputs when those branches change behavior
Applied to files:
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.cs : Keep source generators deterministic and free of hidden environment or network dependencies
Applied to files:
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.cs : Generated logic and source generator pipelines MUST explain what is generated, why it is generated, semantic assumptions the generator relies on, and any diagnostics or fallback behavior
Applied to files:
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs
📚 Learning: 2026-04-06T12:45:43.921Z
Learnt from: GeWuYou
Repo: GeWuYou/GFramework PR: 190
File: GFramework.Game/Config/GameConfigBootstrap.cs:1-3
Timestamp: 2026-04-06T12:45:43.921Z
Learning: In the GeWuYou/GFramework repository, C# files may omit explicit `using System*` imports because the project-wide `GlobalUsings.cs` (referenced via manual global `using` directives) supplies common namespaces (e.g., `System`, `System.Threading`, `System.Threading.Tasks`). During code review, do not flag missing `using System...` directives in `.cs` files as long as `GlobalUsings.cs` is present/used to provide those namespaces.
Applied to files:
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.csGFramework.Game/Config/YamlConfigTextSerializer.csGFramework.Game/Config/YamlConfigTextValidator.csGFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.csGFramework.SourceGenerators/Config/SchemaConfigGenerator.csGFramework.Game.Tests/Config/YamlConfigTextValidatorTests.csGFramework.Game/Config/YamlConfigSchemaValidator.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.cs : Every non-trivial feature, bug fix, or behavior change MUST include tests or an explicit justification for why a test is not practical
Applied to files:
GFramework.Game.Tests/Config/YamlConfigTextValidatorTests.cs
🪛 GitHub Check: Build and Test
GFramework.Game/Config/YamlConfigTextSerializer.cs
[failure] 8-8:
The type or namespace name 'ISerializer' could not be found (are you missing a using directive or an assembly reference?)
[failure] 8-8:
The type or namespace name 'ISerializer' could not be found (are you missing a using directive or an assembly reference?)
[failure] 8-8:
The type or namespace name 'ISerializer' could not be found (are you missing a using directive or an assembly reference?)
[failure] 8-8:
The type or namespace name 'ISerializer' could not be found (are you missing a using directive or an assembly reference?)
[failure] 8-8:
The type or namespace name 'ISerializer' could not be found (are you missing a using directive or an assembly reference?)
[failure] 8-8:
The type or namespace name 'ISerializer' could not be found (are you missing a using directive or an assembly reference?)
🔇 Additional comments (4)
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs (1)
449-456: 这组新增断言很到位。覆盖了新生成 API 的可见性契约(序列化、schema 路径、同步/异步校验),与当前生成器测试模式一致。
Based on learnings "Applies to **/.Tests.cs : Source generator changes MUST be covered by generator tests" and "Applies to **/.Tests.cs : Preserve snapshot-based verification patterns already used in the repository for source generator tests".
GFramework.Game.Tests/Config/YamlConfigTextValidatorTests.cs (1)
36-143: 测试覆盖质量很好。同步/异步入口及关键诊断字段都被断言到了,和这次公开 API 变更匹配。
Based on learnings "Applies to **/.Tests.cs : Public API changes must be covered by unit or integration tests" and "Applies to **/.cs : Every non-trivial feature, bug fix, or behavior change MUST include tests or an explicit justification for why a test is not practical".
GFramework.Game/Config/YamlConfigTextSerializer.cs (1)
8-12: 代码已正确声明了必需的命名空间导入。
YamlDotNet.Serialization和YamlDotNet.Serialization.NamingConventions的using指令已在文件顶部显式声明,YamlDotNet 包(版本 16.3.0)已在项目配置中引用。Lines 8-12 的代码无需任何修改。> Likely an incorrect or invalid review comment.GFramework.Game/Config/YamlConfigSchemaValidator.cs (1)
92-143: 同步/异步加载复用同一解析链路,这个改动方向很好。
LoadAsync与新加的Load最终都走ParseLoadedSchema(...),能有效避免两条解析逻辑后续漂移。
Greptile SummaryThis PR adds YAML text validation and serialization utilities for the config system, wiring them into generated bindings. It introduces Key changes:
Confidence Score: 4/5PR is safe to merge; previous P0/P1 concerns are resolved and remaining items are non-blocking P2 suggestions. The TOCTOU cache-poisoning issue from the prior review round is correctly fixed (timestamp captured before the Load call). The ResolveAbsolutePath duplication concern is resolved by centralizing it in GeneratedConfigCatalog as an internal helper. Test coverage is solid across unit and integration tests. The two remaining P2 items — double filesystem stat per cache miss and per-call serializer construction — are minor efficiency opportunities that do not affect correctness. GFramework.Game/Config/YamlConfigTextValidator.cs — double-stat pattern per cache miss is worth a follow-up cleanup. Important Files Changed
Sequence DiagramsequenceDiagram
participant Host as Host / Editor
participant Binding as GeneratedBinding
participant Validator as YamlConfigTextValidator
participant Cache as SchemaCache
participant FS as File System
participant SchemaVal as YamlConfigSchemaValidator
Host->>Binding: ValidateYaml(rootPath, yamlPath, yamlText)
Binding->>Binding: GetSchemaPath(rootPath)
Binding->>Validator: Validate(tableName, schemaPath, yamlPath, yamlText)
Validator->>FS: GetLastWriteTimeUtc(schemaPath)
FS-->>Validator: T1
alt Cache hit
Validator->>Cache: TryGetValue(key)
Cache-->>Validator: schema
else Cache miss or stale
Validator->>FS: GetLastWriteTimeUtc(schemaPath)
FS-->>Validator: T2
Validator->>SchemaVal: Load(tableName, schemaPath)
SchemaVal->>FS: ReadAllText(schemaPath)
FS-->>SchemaVal: schemaText
SchemaVal-->>Validator: YamlConfigSchema
Validator->>Cache: Store(key, T2, schema)
end
Validator->>SchemaVal: Validate(tableName, schema, yamlPath, yamlText)
SchemaVal-->>Validator: throws ConfigLoadException on failure
Validator-->>Host: throws or returns
Reviews (6): Last reviewed commit: "feat(config): 添加YAML配置文本校验器" | Re-trigger Greptile |
- 实现了 YAML 配置与 JSON Schema 的运行时校验功能 - 支持嵌套对象、对象数组、标量数组的递归校验 - 集成了 enum 和引用约束的深度校验机制 - 实现了 multipleOf、uniqueItems 等扩展约束规则 - 添加了跨表引用收集和校验能力 - 提供了异步和同步两种加载校验接口 - 支持 minContains/maxContains 数组匹配计数规则 - 实现了 minProperties/maxProperties 对象属性数量校验 - 集成了日期时间、邮箱、URI 等字符串格式校验 - 提供了详细的错误诊断信息和定位功能
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
GFramework.Game/Config/YamlConfigSchemaValidator.cs (1)
77-90:⚠️ Potential issue | 🟠 Major修复文件读取异常捕获以避免吞掉取消信号
Line 80 的异步读取显式传入了
cancellationToken,但后续catch (Exception)会将OperationCanceledException包装成SchemaReadFailed,破坏协作取消语义。同时宽泛的异常捕获范围超过了必要的文件 I/O 异常(IOException、UnauthorizedAccessException)。Line 132 的同步版本也有相同的捕获范围问题。修复建议
string schemaText; try { schemaText = await File.ReadAllTextAsync(schemaPath, cancellationToken).ConfigureAwait(false); } - catch (Exception exception) + catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) + { + throw; + } + catch (Exception exception) when (exception is IOException or UnauthorizedAccessException) { throw ConfigLoadExceptionFactory.Create( ConfigLoadFailureKind.SchemaReadFailed, tableName, $"Failed to read schema file '{schemaPath}'.", schemaPath: schemaPath, innerException: exception); } string schemaText; try { schemaText = File.ReadAllText(schemaPath); } - catch (Exception exception) + catch (Exception exception) when (exception is IOException or UnauthorizedAccessException) { throw ConfigLoadExceptionFactory.Create( ConfigLoadFailureKind.SchemaReadFailed, tableName, $"Failed to read schema file '{schemaPath}'.", schemaPath: schemaPath, innerException: exception); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@GFramework.Game/Config/YamlConfigSchemaValidator.cs` around lines 77 - 90, The current catch around File.ReadAllTextAsync(schemaPath, cancellationToken) in YamlConfigSchemaValidator.cs swallows cancellation and is too broad; change the exception handling so OperationCanceledException is rethrown (or not caught) and only IO-related exceptions are wrapped into ConfigLoadExceptionFactory.Create(SchemaReadFailed). Concretely, replace the broad catch (Exception exception) with a catch (OperationCanceledException) { throw; } followed by catch blocks for IOException and UnauthorizedAccessException that call ConfigLoadExceptionFactory.Create (referencing schemaText/File.ReadAllTextAsync, cancellationToken, ConfigLoadFailureKind.SchemaReadFailed, and the existing ConfigLoadExceptionFactory.Create call), and apply the same pattern to the synchronous read path in the same class.
🧹 Nitpick comments (1)
GFramework.Game/Config/YamlConfigTextSerializer.cs (1)
8-12: 建议为缓存的序列化器实例添加线程安全注释。
Serializer是静态共享实例,按照编码规范,应记录线程安全假设。YamlDotNet 的ISerializer在不可变配置下是线程安全的,建议补充注释说明。📝 建议补充
+ // Thread-safety: YamlDotNet ISerializer is thread-safe when built with immutable configuration. + // The instance is created once and reused for all serialization calls. private static readonly ISerializer Serializer = new SerializerBuilder()Based on learnings: "When adding caching, pooling, or shared mutable state, document thread-safety assumptions and failure modes"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@GFramework.Game/Config/YamlConfigTextSerializer.cs` around lines 8 - 12, The static field Serializer (type ISerializer) in YamlConfigTextSerializer.cs is a shared cached instance and needs a thread-safety comment: add a concise doc comment immediately above the private static readonly ISerializer Serializer declaration stating the thread-safety assumption (e.g., that YamlDotNet's ISerializer built with an immutable SerializerBuilder is safe for concurrent reads), mention that the instance is immutable/configured once via SerializerBuilder (WithNamingConvention/DisableAliases/ConfigureDefaultValuesHandling) and note any failure modes or when it would not be safe (if reconfigured or made mutable); this documents why the static Serializer can be reused across threads.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@GFramework.Game/Config/YamlConfigTextSerializer.cs`:
- Around line 1-12: The file YamlConfigTextSerializer fails to compile because
types ISerializer, SerializerBuilder, CamelCaseNamingConvention and
DefaultValuesHandling are from YamlDotNet and missing namespace imports; add the
appropriate using directives (e.g., using YamlDotNet.Serialization; and using
YamlDotNet.Serialization.NamingConventions;) at the top of the file so the
YamlConfigTextSerializer static class can resolve ISerializer,
SerializerBuilder, CamelCaseNamingConvention and DefaultValuesHandling.
---
Outside diff comments:
In `@GFramework.Game/Config/YamlConfigSchemaValidator.cs`:
- Around line 77-90: The current catch around File.ReadAllTextAsync(schemaPath,
cancellationToken) in YamlConfigSchemaValidator.cs swallows cancellation and is
too broad; change the exception handling so OperationCanceledException is
rethrown (or not caught) and only IO-related exceptions are wrapped into
ConfigLoadExceptionFactory.Create(SchemaReadFailed). Concretely, replace the
broad catch (Exception exception) with a catch (OperationCanceledException) {
throw; } followed by catch blocks for IOException and
UnauthorizedAccessException that call ConfigLoadExceptionFactory.Create
(referencing schemaText/File.ReadAllTextAsync, cancellationToken,
ConfigLoadFailureKind.SchemaReadFailed, and the existing
ConfigLoadExceptionFactory.Create call), and apply the same pattern to the
synchronous read path in the same class.
---
Nitpick comments:
In `@GFramework.Game/Config/YamlConfigTextSerializer.cs`:
- Around line 8-12: The static field Serializer (type ISerializer) in
YamlConfigTextSerializer.cs is a shared cached instance and needs a
thread-safety comment: add a concise doc comment immediately above the private
static readonly ISerializer Serializer declaration stating the thread-safety
assumption (e.g., that YamlDotNet's ISerializer built with an immutable
SerializerBuilder is safe for concurrent reads), mention that the instance is
immutable/configured once via SerializerBuilder
(WithNamingConvention/DisableAliases/ConfigureDefaultValuesHandling) and note
any failure modes or when it would not be safe (if reconfigured or made
mutable); this documents why the static Serializer can be reused across threads.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 0aa1b2af-c4f1-49c0-bebd-e1003bd8c387
📒 Files selected for processing (7)
GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.csGFramework.Game.Tests/Config/YamlConfigSchemaValidatorTests.csGFramework.Game/Config/YamlConfigSchemaValidator.csGFramework.Game/Config/YamlConfigTextSerializer.csGFramework.Game/Config/YamlConfigTextValidator.csGFramework.SourceGenerators.Tests/Config/snapshots/SchemaConfigGenerator/MonsterConfigBindings.g.txtGFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
🚧 Files skipped from review as they are similar to previous changes (3)
- GFramework.Game/Config/YamlConfigTextValidator.cs
- GFramework.SourceGenerators.Tests/Config/snapshots/SchemaConfigGenerator/MonsterConfigBindings.g.txt
- GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Analyze (C#)
- GitHub Check: Code Quality & Security
🧰 Additional context used
📓 Path-based instructions (1)
**/*.cs
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.cs: LoggerGenerator must automatically generate log fields and logging helper methods for classes decorated with [Log] attribute
PriorityGenerator must generate priority comparison implementations for classes decorated with [Priority] attribute
EnumExtensionsGenerator must generate enum extension capabilities for enums decorated with [GenerateEnumExtensions] attribute
ContextAwareGenerator must automatically implement IContextAware boilerplate logic for classes decorated with [ContextAware] attribute
**/*.cs: All public, protected, and internal types and members MUST include XML documentation comments (///) with<summary>,<param>,<returns>,<exception>, and<remarks>tags where applicable
XML documentation comments must explain intent, contract, and usage constraints instead of restating syntax
Add inline comments for non-trivial logic, concurrency/threading behavior, performance-sensitive paths, workarounds, compatibility constraints, edge cases, registration order, lifecycle sequencing, and generated code assumptions
Core framework components (Architecture, Module, System, Context, Registry, Service Module, Lifecycle types) MUST include high-level explanations of responsibilities, lifecycle, interactions with other components, why the abstraction exists, and when to use it instead of alternatives
Generated logic and source generator pipelines MUST explain what is generated, why it is generated, semantic assumptions the generator relies on, and any diagnostics or fallback behavior
Methods with non-trivial logic MUST document the core idea, key decisions, and edge case handling
Do not rely on implicit imports; declare every requiredusingexplicitly
Write null-safe code that respects nullable annotations instead of suppressing warnings by default
Use namespace patternGFramework.{Module}.{Feature}with PascalCase segments
Follow standard C# naming: Types/methods/properties/events/constants use PascalCase, interfaces useIprefix, parame...
Files:
GFramework.Game.Tests/Config/YamlConfigSchemaValidatorTests.csGFramework.SourceGenerators/Config/SchemaConfigGenerator.csGFramework.Game/Config/YamlConfigSchemaValidator.csGFramework.Game/Config/YamlConfigTextSerializer.cs
🧠 Learnings (13)
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.Tests.cs : Public API changes must be covered by unit or integration tests
Applied to files:
GFramework.Game.Tests/Config/YamlConfigSchemaValidatorTests.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.Tests.cs : Source generator changes MUST be covered by generator tests
Applied to files:
GFramework.Game.Tests/Config/YamlConfigSchemaValidatorTests.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.Tests.cs : Regression fixes should include a test that fails before the fix and passes after it
Applied to files:
GFramework.Game.Tests/Config/YamlConfigSchemaValidatorTests.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.Tests.cs : Preserve snapshot-based verification patterns already used in the repository for source generator tests
Applied to files:
GFramework.Game.Tests/Config/YamlConfigSchemaValidatorTests.cs
📚 Learning: 2026-04-06T12:45:43.921Z
Learnt from: GeWuYou
Repo: GeWuYou/GFramework PR: 190
File: GFramework.Game/Config/GameConfigBootstrap.cs:1-3
Timestamp: 2026-04-06T12:45:43.921Z
Learning: In the GeWuYou/GFramework repository, C# files may omit explicit `using System*` imports because the project-wide `GlobalUsings.cs` (referenced via manual global `using` directives) supplies common namespaces (e.g., `System`, `System.Threading`, `System.Threading.Tasks`). During code review, do not flag missing `using System...` directives in `.cs` files as long as `GlobalUsings.cs` is present/used to provide those namespaces.
Applied to files:
GFramework.Game.Tests/Config/YamlConfigSchemaValidatorTests.csGFramework.SourceGenerators/Config/SchemaConfigGenerator.csGFramework.Game/Config/YamlConfigSchemaValidator.csGFramework.Game/Config/YamlConfigTextSerializer.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.cs : When generator behavior changes intentionally, update snapshots together with the implementation
Applied to files:
GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.cs : All public, protected, and internal types and members MUST include XML documentation comments (`///`) with `<summary>`, `<param>`, `<returns>`, `<exception>`, and `<remarks>` tags where applicable
Applied to files:
GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.cs : Any change to public API, lifecycle semantics, module behavior, or extension points MUST update the related XML docs
Applied to files:
GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.cs : Add inline comments for non-trivial logic, concurrency/threading behavior, performance-sensitive paths, workarounds, compatibility constraints, edge cases, registration order, lifecycle sequencing, and generated code assumptions
Applied to files:
GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.cs : XML documentation comments must explain intent, contract, and usage constraints instead of restating syntax
Applied to files:
GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.cs : Generated logic and source generator pipelines MUST explain what is generated, why it is generated, semantic assumptions the generator relies on, and any diagnostics or fallback behavior
Applied to files:
GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.cs : Preserve deterministic behavior in registries, lifecycle orchestration, and generated outputs
Applied to files:
GFramework.Game/Config/YamlConfigSchemaValidator.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.cs : When adding caching, pooling, or shared mutable state, document thread-safety assumptions and failure modes
Applied to files:
GFramework.Game/Config/YamlConfigTextSerializer.cs
🪛 GitHub Check: Build and Test
GFramework.Game/Config/YamlConfigTextSerializer.cs
[failure] 8-8:
The type or namespace name 'ISerializer' could not be found (are you missing a using directive or an assembly reference?)
[failure] 8-8:
The type or namespace name 'ISerializer' could not be found (are you missing a using directive or an assembly reference?)
[failure] 8-8:
The type or namespace name 'ISerializer' could not be found (are you missing a using directive or an assembly reference?)
[failure] 8-8:
The type or namespace name 'ISerializer' could not be found (are you missing a using directive or an assembly reference?)
[failure] 8-8:
The type or namespace name 'ISerializer' could not be found (are you missing a using directive or an assembly reference?)
[failure] 8-8:
The type or namespace name 'ISerializer' could not be found (are you missing a using directive or an assembly reference?)
🔇 Additional comments (4)
GFramework.Game/Config/YamlConfigSchemaValidator.cs (2)
268-276: 引用表名排序实现正确,确保输出稳定性这里将
HashSet结果按StringComparer.Ordinal排序后再构建YamlConfigSchema,能稳定热重载依赖推导与测试结果。Based on learnings "Preserve deterministic behavior in registries, lifecycle orchestration, and generated outputs".
3285-3365: 节点工厂方法重排后可读性更好,语义保持清晰
CreateObject / CreateArray / CreateScalar的组织更直观,且 XML 注释与参数契约完整。GFramework.Game.Tests/Config/YamlConfigSchemaValidatorTests.cs (1)
41-71: 回归测试覆盖点准确,能锁定排序确定性行为这个用例对引用表收集后的序数排序结果做了直接断言,和本次修复目标一致。
Based on learnings "Regression fixes should include a test that fails before the fix and passes after it".
GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs (1)
1678-1806: LGTM! YAML 序列化辅助方法生成逻辑正确。新增的
AppendYamlSerializationHelpers方法为生成的绑定类输出完整的 YAML 序列化与验证辅助 API,包括:
SerializeToYaml:委托到共享序列化器GetConfigDirectoryPath/GetSchemaPath:路径解析ValidateYaml/ValidateYamlAsync:委托到运行时验证器生成的 XML 文档包含了
<exception>契约,符合编码规范要求。路径规范化逻辑(Lines 1799-1804)正确处理了正斜杠和反斜杠到平台目录分隔符的转换。
- 新增YamlConfigTextSerializer类提供统一的YAML序列化功能 - 集成测试中添加配置抽象接口引用 - 序列化器使用驼峰命名约定和默认值保留策略 - 自动确保YAML输出以换行符结尾 - 配置对象序列化时验证空值并抛出异常
- 实现YamlConfigTextSerializer提供YAML文本序列化功能 - 实现YamlConfigTextValidator提供YAML文本校验功能 - 添加缓存机制优化schema文件加载性能 - 实现同步和异步校验接口支持 - 添加集成测试验证生成配置绑定功能 - 扩展SchemaConfigGenerator支持配置类型生成 - 实现GeneratedConfigConsumerIntegrationTests完整测试覆盖
- 为Validate方法添加详细的remarks文档说明同步加载schema的特性 - 为ValidateAsync方法添加cancellation token异常说明和异步加载schema的详细文档 - 补充异步验证方法的I/O密集场景适用性说明
- 实现同步和异步YAML文本校验功能 - 添加基于schema文件的配置校验支持 - 实现schema缓存机制避免重复磁盘IO - 提供配置表名称和文件路径参数验证 - 集成取消令牌支持异步操作取消 - 添加详细的异常处理和诊断信息
由 Sourcery 提供的摘要
向宿主公开面向主机的 YAML 模式验证和序列化工具,并将其接入到生成的配置绑定中。
新功能:
增强:
测试:
Original summary in English
Summary by Sourcery
Expose host-facing YAML schema validation and serialization utilities and wire them into generated config bindings.
New Features:
Enhancements:
Tests:
Summary by CodeRabbit
新功能
修复 / 行为改进
测试