diff --git a/GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs b/GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs
new file mode 100644
index 00000000..a419c260
--- /dev/null
+++ b/GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs
@@ -0,0 +1,125 @@
+using System.IO;
+using GFramework.Game.Config;
+using GFramework.Game.Config.Generated;
+
+namespace GFramework.Game.Tests.Config;
+
+///
+/// 验证消费者项目通过 `schemas/**/*.schema.json` 自动拾取 schema 后,
+/// 可以直接编译并使用生成的注册辅助、强类型访问入口与运行时加载链路。
+///
+[TestFixture]
+public class GeneratedConfigConsumerIntegrationTests
+{
+ ///
+ /// 为每个端到端测试准备独立的配置根目录,避免编译期 schema 资产与运行时写入互相污染。
+ ///
+ [SetUp]
+ public void SetUp()
+ {
+ _rootPath = Path.Combine(Path.GetTempPath(), "GFramework.GeneratedConfigTests", Guid.NewGuid().ToString("N"));
+ Directory.CreateDirectory(_rootPath);
+ }
+
+ ///
+ /// 清理测试过程中创建的临时消费者目录。
+ ///
+ [TearDown]
+ public void TearDown()
+ {
+ if (Directory.Exists(_rootPath))
+ {
+ Directory.Delete(_rootPath, true);
+ }
+ }
+
+ private string _rootPath = null!;
+
+ ///
+ /// 验证生成器自动拾取消费者项目的 schema 后,
+ /// 可以用生成的注册辅助完成加载,并通过强类型表包装访问运行时数据。
+ ///
+ [Test]
+ public async Task LoadAsync_Should_Support_Generated_Bindings_In_Consumer_Project()
+ {
+ CreateFile(
+ "schemas/monster.schema.json",
+ """
+ {
+ "title": "Monster Config",
+ "description": "Defines one monster entry for the end-to-end consumer integration test.",
+ "type": "object",
+ "required": ["id", "name", "hp"],
+ "properties": {
+ "id": {
+ "type": "integer",
+ "description": "Monster identifier."
+ },
+ "name": {
+ "type": "string",
+ "description": "Monster display name."
+ },
+ "hp": {
+ "type": "integer",
+ "description": "Monster base health."
+ }
+ }
+ }
+ """);
+ CreateFile(
+ "monster/slime.yaml",
+ """
+ id: 1
+ name: Slime
+ hp: 10
+ """);
+ CreateFile(
+ "monster/goblin.yaml",
+ """
+ id: 2
+ name: Goblin
+ hp: 30
+ """);
+
+ var registry = new ConfigRegistry();
+ var loader = new YamlConfigLoader(_rootPath)
+ .RegisterMonsterTable();
+
+ await loader.LoadAsync(registry);
+
+ var table = registry.GetMonsterTable();
+
+ Assert.Multiple(() =>
+ {
+ 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(table.Count, Is.EqualTo(2));
+ Assert.That(table.Get(1).Name, Is.EqualTo("Slime"));
+ Assert.That(table.Get(2).Hp, Is.EqualTo(30));
+ Assert.That(registry.TryGetMonsterTable(out var generatedTable), Is.True);
+ Assert.That(generatedTable, Is.Not.Null);
+ Assert.That(generatedTable!.All().Select(static config => config.Name),
+ Is.EquivalentTo(new[] { "Slime", "Goblin" }));
+ });
+ }
+
+ ///
+ /// 在临时消费者根目录中创建测试文件。
+ ///
+ /// 相对根目录的文件路径。
+ /// 要写入的文件内容。
+ private void CreateFile(
+ string relativePath,
+ string content)
+ {
+ var path = Path.Combine(_rootPath, relativePath.Replace('/', Path.DirectorySeparatorChar));
+ var directoryPath = Path.GetDirectoryName(path);
+ if (!string.IsNullOrEmpty(directoryPath))
+ {
+ Directory.CreateDirectory(directoryPath);
+ }
+
+ File.WriteAllText(path, content.Replace("\n", Environment.NewLine, StringComparison.Ordinal));
+ }
+}
\ No newline at end of file
diff --git a/GFramework.Game.Tests/GFramework.Game.Tests.csproj b/GFramework.Game.Tests/GFramework.Game.Tests.csproj
index 7df909e8..6ad45dbe 100644
--- a/GFramework.Game.Tests/GFramework.Game.Tests.csproj
+++ b/GFramework.Game.Tests/GFramework.Game.Tests.csproj
@@ -19,6 +19,21 @@
+
+
+
+
+
+
diff --git a/GFramework.Game.Tests/schemas/monster.schema.json b/GFramework.Game.Tests/schemas/monster.schema.json
new file mode 100644
index 00000000..4b16aa59
--- /dev/null
+++ b/GFramework.Game.Tests/schemas/monster.schema.json
@@ -0,0 +1,24 @@
+{
+ "title": "Monster Config",
+ "description": "Defines one monster entry for the generated consumer integration test.",
+ "type": "object",
+ "required": [
+ "id",
+ "name",
+ "hp"
+ ],
+ "properties": {
+ "id": {
+ "type": "integer",
+ "description": "Monster identifier."
+ },
+ "name": {
+ "type": "string",
+ "description": "Monster display name."
+ },
+ "hp": {
+ "type": "integer",
+ "description": "Monster base health."
+ }
+ }
+}
diff --git a/GFramework.SourceGenerators/GeWuYou.GFramework.SourceGenerators.targets b/GFramework.SourceGenerators/GeWuYou.GFramework.SourceGenerators.targets
index b66b376d..c2c3af2d 100644
--- a/GFramework.SourceGenerators/GeWuYou.GFramework.SourceGenerators.targets
+++ b/GFramework.SourceGenerators/GeWuYou.GFramework.SourceGenerators.targets
@@ -12,9 +12,17 @@
-
-
-
+
+
+
+