diff --git a/GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs b/GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs
index a419c260..d9aee6da 100644
--- a/GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs
+++ b/GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs
@@ -91,9 +91,16 @@ public class GeneratedConfigConsumerIntegrationTests
Assert.Multiple(() =>
{
+ Assert.That(MonsterConfigBindings.ConfigDomain, Is.EqualTo("monster"));
Assert.That(MonsterConfigBindings.TableName, Is.EqualTo("monster"));
Assert.That(MonsterConfigBindings.ConfigRelativePath, Is.EqualTo("monster"));
Assert.That(MonsterConfigBindings.SchemaRelativePath, Is.EqualTo("schemas/monster.schema.json"));
+ Assert.That(MonsterConfigBindings.Metadata.ConfigDomain, Is.EqualTo(MonsterConfigBindings.ConfigDomain));
+ Assert.That(MonsterConfigBindings.Metadata.TableName, Is.EqualTo(MonsterConfigBindings.TableName));
+ Assert.That(MonsterConfigBindings.Metadata.ConfigRelativePath,
+ Is.EqualTo(MonsterConfigBindings.ConfigRelativePath));
+ Assert.That(MonsterConfigBindings.Metadata.SchemaRelativePath,
+ Is.EqualTo(MonsterConfigBindings.SchemaRelativePath));
Assert.That(table.Count, Is.EqualTo(2));
Assert.That(table.Get(1).Name, Is.EqualTo("Slime"));
Assert.That(table.Get(2).Hp, Is.EqualTo(30));
diff --git a/GFramework.SourceGenerators.Tests/Config/snapshots/SchemaConfigGenerator/MonsterConfigBindings.g.txt b/GFramework.SourceGenerators.Tests/Config/snapshots/SchemaConfigGenerator/MonsterConfigBindings.g.txt
index a2954ce7..36c4dbcc 100644
--- a/GFramework.SourceGenerators.Tests/Config/snapshots/SchemaConfigGenerator/MonsterConfigBindings.g.txt
+++ b/GFramework.SourceGenerators.Tests/Config/snapshots/SchemaConfigGenerator/MonsterConfigBindings.g.txt
@@ -9,20 +9,51 @@ namespace GFramework.Game.Config.Generated;
///
public static class MonsterConfigBindings
{
+ ///
+ /// Groups the schema-derived metadata constants so consumer code can reuse one stable entry point.
+ ///
+ public static class Metadata
+ {
+ ///
+ /// Gets the logical config domain derived from the schema base name. The current runtime convention keeps this value aligned with the generated table name.
+ ///
+ public const string ConfigDomain = "monster";
+
+ ///
+ /// Gets the runtime registration name of the generated config table.
+ ///
+ public const string TableName = "monster";
+
+ ///
+ /// Gets the config directory path expected by the generated registration helper.
+ ///
+ public const string ConfigRelativePath = "monster";
+
+ ///
+ /// Gets the schema file path expected by the generated registration helper.
+ ///
+ public const string SchemaRelativePath = "schemas/monster.schema.json";
+ }
+
+ ///
+ /// Gets the logical config domain derived from the schema base name. The current runtime convention keeps this value aligned with the generated table name.
+ ///
+ public const string ConfigDomain = Metadata.ConfigDomain;
+
///
/// Gets the runtime registration name of the generated config table.
///
- public const string TableName = "monster";
+ public const string TableName = Metadata.TableName;
///
/// Gets the config directory path expected by the generated registration helper.
///
- public const string ConfigRelativePath = "monster";
+ public const string ConfigRelativePath = Metadata.ConfigRelativePath;
///
/// Gets the schema file path expected by the generated registration helper.
///
- public const string SchemaRelativePath = "schemas/monster.schema.json";
+ public const string SchemaRelativePath = Metadata.SchemaRelativePath;
///
/// Registers the generated config table using the schema-derived runtime conventions.
@@ -40,9 +71,9 @@ public static class MonsterConfigBindings
}
return loader.RegisterTable(
- TableName,
- ConfigRelativePath,
- SchemaRelativePath,
+ Metadata.TableName,
+ Metadata.ConfigRelativePath,
+ Metadata.SchemaRelativePath,
static config => config.Id,
comparer);
}
@@ -60,7 +91,7 @@ public static class MonsterConfigBindings
throw new global::System.ArgumentNullException(nameof(registry));
}
- return new MonsterTable(registry.GetTable(TableName));
+ return new MonsterTable(registry.GetTable(Metadata.TableName));
}
///
@@ -77,7 +108,7 @@ public static class MonsterConfigBindings
throw new global::System.ArgumentNullException(nameof(registry));
}
- if (registry.TryGetTable(TableName, out var innerTable) && innerTable is not null)
+ if (registry.TryGetTable(Metadata.TableName, out var innerTable) && innerTable is not null)
{
table = new MonsterTable(innerTable);
return true;
diff --git a/GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs b/GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
index c0e5560d..96956f8b 100644
--- a/GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
+++ b/GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
@@ -650,22 +650,58 @@ public sealed class SchemaConfigGenerator : IIncrementalGenerator
builder.AppendLine($"public static class {bindingsClassName}");
builder.AppendLine("{");
builder.AppendLine(" /// ");
+ builder.AppendLine(
+ " /// Groups the schema-derived metadata constants so consumer code can reuse one stable entry point.");
+ builder.AppendLine(" /// ");
+ builder.AppendLine(" public static class Metadata");
+ builder.AppendLine(" {");
+ builder.AppendLine(" /// ");
+ builder.AppendLine(
+ " /// Gets the logical config domain derived from the schema base name. The current runtime convention keeps this value aligned with the generated table name.");
+ builder.AppendLine(" /// ");
+ builder.AppendLine(
+ $" public const string ConfigDomain = {SymbolDisplay.FormatLiteral(schema.TableRegistrationName, true)};");
+ builder.AppendLine();
+ builder.AppendLine(" /// ");
+ builder.AppendLine(" /// Gets the runtime registration name of the generated config table.");
+ builder.AppendLine(" /// ");
+ builder.AppendLine(
+ $" public const string TableName = {SymbolDisplay.FormatLiteral(schema.TableRegistrationName, true)};");
+ builder.AppendLine();
+ builder.AppendLine(" /// ");
+ builder.AppendLine(
+ " /// Gets the config directory path expected by the generated registration helper.");
+ builder.AppendLine(" /// ");
+ builder.AppendLine(
+ $" public const string ConfigRelativePath = {SymbolDisplay.FormatLiteral(schema.ConfigRelativePath, true)};");
+ builder.AppendLine();
+ builder.AppendLine(" /// ");
+ builder.AppendLine(" /// Gets the schema file path expected by the generated registration helper.");
+ builder.AppendLine(" /// ");
+ builder.AppendLine(
+ $" public const string SchemaRelativePath = {SymbolDisplay.FormatLiteral(schema.SchemaRelativePath, true)};");
+ builder.AppendLine(" }");
+ builder.AppendLine();
+ builder.AppendLine(" /// ");
+ builder.AppendLine(
+ " /// Gets the logical config domain derived from the schema base name. The current runtime convention keeps this value aligned with the generated table name.");
+ builder.AppendLine(" /// ");
+ builder.AppendLine(" public const string ConfigDomain = Metadata.ConfigDomain;");
+ builder.AppendLine();
+ builder.AppendLine(" /// ");
builder.AppendLine(" /// Gets the runtime registration name of the generated config table.");
builder.AppendLine(" /// ");
- builder.AppendLine(
- $" public const string TableName = {SymbolDisplay.FormatLiteral(schema.TableRegistrationName, true)};");
+ builder.AppendLine(" public const string TableName = Metadata.TableName;");
builder.AppendLine();
builder.AppendLine(" /// ");
builder.AppendLine(" /// Gets the config directory path expected by the generated registration helper.");
builder.AppendLine(" /// ");
- builder.AppendLine(
- $" public const string ConfigRelativePath = {SymbolDisplay.FormatLiteral(schema.ConfigRelativePath, true)};");
+ builder.AppendLine(" public const string ConfigRelativePath = Metadata.ConfigRelativePath;");
builder.AppendLine();
builder.AppendLine(" /// ");
builder.AppendLine(" /// Gets the schema file path expected by the generated registration helper.");
builder.AppendLine(" /// ");
- builder.AppendLine(
- $" public const string SchemaRelativePath = {SymbolDisplay.FormatLiteral(schema.SchemaRelativePath, true)};");
+ builder.AppendLine(" public const string SchemaRelativePath = Metadata.SchemaRelativePath;");
builder.AppendLine();
builder.AppendLine(" /// ");
builder.AppendLine(
@@ -688,9 +724,9 @@ public sealed class SchemaConfigGenerator : IIncrementalGenerator
builder.AppendLine();
builder.AppendLine(
$" return loader.RegisterTable<{schema.KeyClrType}, {schema.ClassName}>(");
- builder.AppendLine(" TableName,");
- builder.AppendLine(" ConfigRelativePath,");
- builder.AppendLine(" SchemaRelativePath,");
+ builder.AppendLine(" Metadata.TableName,");
+ builder.AppendLine(" Metadata.ConfigRelativePath,");
+ builder.AppendLine(" Metadata.SchemaRelativePath,");
builder.AppendLine($" static config => config.{schema.KeyPropertyName},");
builder.AppendLine(" comparer);");
builder.AppendLine(" }");
@@ -711,7 +747,7 @@ public sealed class SchemaConfigGenerator : IIncrementalGenerator
builder.AppendLine(" }");
builder.AppendLine();
builder.AppendLine(
- $" return new {schema.TableName}(registry.GetTable<{schema.KeyClrType}, {schema.ClassName}>(TableName));");
+ $" return new {schema.TableName}(registry.GetTable<{schema.KeyClrType}, {schema.ClassName}>(Metadata.TableName));");
builder.AppendLine(" }");
builder.AppendLine();
builder.AppendLine(" /// ");
@@ -733,7 +769,7 @@ public sealed class SchemaConfigGenerator : IIncrementalGenerator
builder.AppendLine(" }");
builder.AppendLine();
builder.AppendLine(
- $" if (registry.TryGetTable<{schema.KeyClrType}, {schema.ClassName}>(TableName, out var innerTable) && innerTable is not null)");
+ $" if (registry.TryGetTable<{schema.KeyClrType}, {schema.ClassName}>(Metadata.TableName, out var innerTable) && innerTable is not null)");
builder.AppendLine(" {");
builder.AppendLine($" table = new {schema.TableName}(innerTable);");
builder.AppendLine(" return true;");
diff --git a/docs/zh-CN/game/config-system.md b/docs/zh-CN/game/config-system.md
index 03331442..163cbca4 100644
--- a/docs/zh-CN/game/config-system.md
+++ b/docs/zh-CN/game/config-system.md
@@ -103,11 +103,21 @@ var slime = monsterTable.Get(1);
这组辅助会把以下约定固化到生成代码里:
+- 配置域常量,例如 `MonsterConfigBindings.ConfigDomain`
- 表注册名,例如 `monster`
- 配置目录相对路径,例如 `monster`
- schema 相对路径,例如 `schemas/monster.schema.json`
- 主键提取逻辑,例如 `config => config.Id`
+如果你希望把这些约定作为一个统一入口传递或复用,也可以优先读取 `MonsterConfigBindings.Metadata` 下的常量:
+
+```csharp
+var domain = MonsterConfigBindings.Metadata.ConfigDomain;
+var tableName = MonsterConfigBindings.Metadata.TableName;
+var configPath = MonsterConfigBindings.Metadata.ConfigRelativePath;
+var schemaPath = MonsterConfigBindings.Metadata.SchemaRelativePath;
+```
+
如果你需要自定义目录、表名或 key selector,仍然可以直接调用 `YamlConfigLoader.RegisterTable(...)` 原始重载。
## 运行时校验行为