mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-05-07 00:39:00 +08:00
docs(config): 添加游戏内容配置系统文档
- 新增 CQRS 架构模式详细文档,包括命令查询职责分离核心概念 - 添加命令、查询、处理器、请求分发器等基本用法示例 - 包含高级用法如通知、管道行为、流式处理等完整功能介绍 - 提供最佳实践指南和常见问题解决方案 - 添加游戏内容配置系统文档,涵盖 YAML 配置源文件和 JSON Schema 结构描述 - 包含推荐目录结构、Schema 示例和 YAML 示例配置 - 提供完整的接入模板,包括 csproj 配置、启动帮助器和运行时读取模板 - 添加 Godot 文本配置桥接、热重载和 Architecture 接入等高级功能说明
This commit is contained in:
parent
09f751a4f7
commit
0cf4945e78
@ -1,4 +1,4 @@
|
||||
namespace GFramework.SourceGenerators.Abstractions.Architectures;
|
||||
namespace GFramework.Core.SourceGenerators.Abstractions.Architectures;
|
||||
|
||||
/// <summary>
|
||||
/// 标记架构模块类型,Source Generator 会根据注册特性生成 <c>Install</c> 方法。
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.SourceGenerators.Abstractions.Architectures;
|
||||
namespace GFramework.Core.SourceGenerators.Abstractions.Architectures;
|
||||
|
||||
/// <summary>
|
||||
/// 声明架构模块需要自动注册的模型类型。
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.SourceGenerators.Abstractions.Architectures;
|
||||
namespace GFramework.Core.SourceGenerators.Abstractions.Architectures;
|
||||
|
||||
/// <summary>
|
||||
/// 声明架构模块需要自动注册的系统类型。
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.SourceGenerators.Abstractions.Architectures;
|
||||
namespace GFramework.Core.SourceGenerators.Abstractions.Architectures;
|
||||
|
||||
/// <summary>
|
||||
/// 声明架构模块需要自动注册的工具类型。
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.SourceGenerators.Abstractions.Bases;
|
||||
namespace GFramework.Core.SourceGenerators.Abstractions.Bases;
|
||||
|
||||
/// <summary>
|
||||
/// 标记类的优先级,自动生成 <c>GFramework.Core.Abstractions.Bases.IPrioritized</c> 接口实现。
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.SourceGenerators.Abstractions.Enums;
|
||||
namespace GFramework.Core.SourceGenerators.Abstractions.Enums;
|
||||
|
||||
/// <summary>
|
||||
/// 标注在 enum 上,Source Generator 会为该 enum 生成扩展方法。
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#nullable enable
|
||||
namespace GFramework.SourceGenerators.Abstractions.Logging;
|
||||
namespace GFramework.Core.SourceGenerators.Abstractions.Logging;
|
||||
|
||||
/// <summary>
|
||||
/// 标注在类上,Source Generator 会为该类自动生成一个日志记录器字段。
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.SourceGenerators.Abstractions.Rule;
|
||||
namespace GFramework.Core.SourceGenerators.Abstractions.Rule;
|
||||
|
||||
/// <summary>
|
||||
/// 标记该类需要自动实现 IContextAware
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.SourceGenerators.Abstractions.Rule;
|
||||
namespace GFramework.Core.SourceGenerators.Abstractions.Rule;
|
||||
|
||||
/// <summary>
|
||||
/// 标记类需要自动推断并注入上下文相关字段。
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.SourceGenerators.Abstractions.Rule;
|
||||
namespace GFramework.Core.SourceGenerators.Abstractions.Rule;
|
||||
|
||||
/// <summary>
|
||||
/// 标记字段需要自动注入单个模型实例。
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.SourceGenerators.Abstractions.Rule;
|
||||
namespace GFramework.Core.SourceGenerators.Abstractions.Rule;
|
||||
|
||||
/// <summary>
|
||||
/// 标记字段需要自动注入模型集合。
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.SourceGenerators.Abstractions.Rule;
|
||||
namespace GFramework.Core.SourceGenerators.Abstractions.Rule;
|
||||
|
||||
/// <summary>
|
||||
/// 标记字段需要自动注入单个服务实例。
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.SourceGenerators.Abstractions.Rule;
|
||||
namespace GFramework.Core.SourceGenerators.Abstractions.Rule;
|
||||
|
||||
/// <summary>
|
||||
/// 标记字段需要自动注入服务集合。
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.SourceGenerators.Abstractions.Rule;
|
||||
namespace GFramework.Core.SourceGenerators.Abstractions.Rule;
|
||||
|
||||
/// <summary>
|
||||
/// 标记字段需要自动注入单个系统实例。
|
||||
|
||||
@ -1,8 +1,22 @@
|
||||
namespace GFramework.SourceGenerators.Abstractions.Rule;
|
||||
namespace GFramework.Core.SourceGenerators.Abstractions.Rule;
|
||||
|
||||
/// <summary>
|
||||
/// 标记字段需要自动注入系统集合。
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Source Generator 会为标记字段生成从当前架构上下文收集系统实例的注入代码,用于避免在组件内部重复书写
|
||||
/// <c>GetSystems()</c> 一类的样板访问逻辑。
|
||||
/// 被标记字段应声明为可承载多个系统实例的类型,例如 <c>IEnumerable<ISystem></c> 或兼容集合接口。
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// public partial class CombatPanel : IContextAware
|
||||
/// {
|
||||
/// [GetSystems]
|
||||
/// private IEnumerable<ISystem> _systems = Array.Empty<ISystem>();
|
||||
/// }
|
||||
/// </code>
|
||||
/// </example>
|
||||
[AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
|
||||
public sealed class GetSystemsAttribute : Attribute
|
||||
{
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.SourceGenerators.Abstractions.Rule;
|
||||
namespace GFramework.Core.SourceGenerators.Abstractions.Rule;
|
||||
|
||||
/// <summary>
|
||||
/// 标记字段需要自动注入工具集合。
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.SourceGenerators.Abstractions.Rule;
|
||||
namespace GFramework.Core.SourceGenerators.Abstractions.Rule;
|
||||
|
||||
/// <summary>
|
||||
/// 标记字段需要自动注入单个工具实例。
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
using GFramework.Core.SourceGenerators.Diagnostics;
|
||||
using GFramework.SourceGenerators.Common.Constants;
|
||||
using GFramework.SourceGenerators.Diagnostics;
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
using Microsoft.CodeAnalysis.Operations;
|
||||
|
||||
namespace GFramework.SourceGenerators.Analyzers;
|
||||
namespace GFramework.Core.SourceGenerators.Analyzers;
|
||||
|
||||
/// <summary>
|
||||
/// 分析 Context Get 使用点是否能在所属架构中找到静态可见的 Model、System、Utility 注册。
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
using GFramework.SourceGenerators.Diagnostics;
|
||||
using GFramework.Core.SourceGenerators.Diagnostics;
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
using Microsoft.CodeAnalysis.Operations;
|
||||
|
||||
namespace GFramework.SourceGenerators.Analyzers;
|
||||
namespace GFramework.Core.SourceGenerators.Analyzers;
|
||||
|
||||
/// <summary>
|
||||
/// 优先级使用分析器,检测应该使用 GetAllByPriority 而非 GetAll 的场景
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
using GFramework.SourceGenerators.Abstractions.Architectures;
|
||||
using GFramework.Core.SourceGenerators.Abstractions.Architectures;
|
||||
using GFramework.Core.SourceGenerators.Diagnostics;
|
||||
using GFramework.SourceGenerators.Common.Constants;
|
||||
using GFramework.SourceGenerators.Common.Diagnostics;
|
||||
using GFramework.SourceGenerators.Common.Extensions;
|
||||
using GFramework.SourceGenerators.Diagnostics;
|
||||
|
||||
namespace GFramework.SourceGenerators.Architectures;
|
||||
namespace GFramework.Core.SourceGenerators.Architectures;
|
||||
|
||||
/// <summary>
|
||||
/// 为标记了 <see cref="AutoRegisterModuleAttribute" /> 的模块生成固定顺序的组件注册代码。
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
using GFramework.Core.SourceGenerators.Diagnostics;
|
||||
using GFramework.SourceGenerators.Common.Constants;
|
||||
using GFramework.SourceGenerators.Common.Generator;
|
||||
using GFramework.SourceGenerators.Diagnostics;
|
||||
|
||||
namespace GFramework.SourceGenerators.Bases;
|
||||
namespace GFramework.Core.SourceGenerators.Bases;
|
||||
|
||||
/// <summary>
|
||||
/// Priority 特性生成器,为标记了 [Priority] 的类自动生成 IPrioritized 接口实现
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
using GFramework.SourceGenerators.Common.Constants;
|
||||
|
||||
namespace GFramework.SourceGenerators.Diagnostics;
|
||||
namespace GFramework.Core.SourceGenerators.Diagnostics;
|
||||
|
||||
internal static class AutoRegisterModuleDiagnostics
|
||||
{
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.SourceGenerators.Diagnostics;
|
||||
namespace GFramework.Core.SourceGenerators.Diagnostics;
|
||||
|
||||
/// <summary>
|
||||
/// 提供与上下文感知相关的诊断规则定义
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
using GFramework.SourceGenerators.Common.Constants;
|
||||
|
||||
namespace GFramework.SourceGenerators.Diagnostics;
|
||||
namespace GFramework.Core.SourceGenerators.Diagnostics;
|
||||
|
||||
/// <summary>
|
||||
/// 提供 Context Get 注入生成器相关诊断。
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
using GFramework.SourceGenerators.Common.Constants;
|
||||
|
||||
namespace GFramework.SourceGenerators.Diagnostics;
|
||||
namespace GFramework.Core.SourceGenerators.Diagnostics;
|
||||
|
||||
/// <summary>
|
||||
/// 提供 Context Get 注册可见性分析相关诊断。
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.SourceGenerators.Diagnostics;
|
||||
namespace GFramework.Core.SourceGenerators.Diagnostics;
|
||||
|
||||
/// <summary>
|
||||
/// 提供诊断描述符的静态类,用于GFramework日志生成器的编译时检查
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.SourceGenerators.Diagnostics;
|
||||
namespace GFramework.Core.SourceGenerators.Diagnostics;
|
||||
|
||||
/// <summary>
|
||||
/// Priority 特性相关的诊断信息
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
using GFramework.SourceGenerators.Common.Diagnostics;
|
||||
using GFramework.SourceGenerators.Common.Generator;
|
||||
|
||||
namespace GFramework.SourceGenerators.Enums;
|
||||
namespace GFramework.Core.SourceGenerators.Enums;
|
||||
|
||||
/// <summary>
|
||||
/// 枚举扩展方法生成器,用于自动生成枚举相关的扩展方法
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
using GFramework.SourceGenerators.Abstractions.Logging;
|
||||
using GFramework.Core.SourceGenerators.Abstractions.Logging;
|
||||
using GFramework.SourceGenerators.Common.Constants;
|
||||
using GFramework.SourceGenerators.Common.Extensions;
|
||||
using GFramework.SourceGenerators.Common.Generator;
|
||||
|
||||
namespace GFramework.SourceGenerators.Logging;
|
||||
namespace GFramework.Core.SourceGenerators.Logging;
|
||||
|
||||
/// <summary>
|
||||
/// 日志生成器,用于为标记了LogAttribute的类自动生成日志字段
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
using GFramework.SourceGenerators.Common.Constants;
|
||||
using GFramework.Core.SourceGenerators.Diagnostics;
|
||||
using GFramework.SourceGenerators.Common.Constants;
|
||||
using GFramework.SourceGenerators.Common.Diagnostics;
|
||||
using GFramework.SourceGenerators.Common.Generator;
|
||||
using GFramework.SourceGenerators.Diagnostics;
|
||||
|
||||
namespace GFramework.SourceGenerators.Rule;
|
||||
namespace GFramework.Core.SourceGenerators.Rule;
|
||||
|
||||
/// <summary>
|
||||
/// 上下文感知生成器,用于为标记了ContextAware特性的类自动生成IContextAware接口实现
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
using GFramework.Core.SourceGenerators.Diagnostics;
|
||||
using GFramework.SourceGenerators.Common.Constants;
|
||||
using GFramework.SourceGenerators.Common.Diagnostics;
|
||||
using GFramework.SourceGenerators.Common.Extensions;
|
||||
using GFramework.SourceGenerators.Common.Info;
|
||||
using GFramework.SourceGenerators.Diagnostics;
|
||||
|
||||
namespace GFramework.SourceGenerators.Rule;
|
||||
namespace GFramework.Core.SourceGenerators.Rule;
|
||||
|
||||
/// <summary>
|
||||
/// 为上下文感知类生成 Core 上下文 Get 注入方法。
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
using GFramework.SourceGenerators.Common.Constants;
|
||||
|
||||
namespace GFramework.SourceGenerators.Cqrs;
|
||||
namespace GFramework.Cqrs.SourceGenerators.Cqrs;
|
||||
|
||||
/// <summary>
|
||||
/// 为当前编译程序集生成 CQRS 处理器注册器,以减少运行时的程序集反射扫描成本。
|
||||
@ -347,7 +347,7 @@ public sealed class CqrsHandlerRegistryGenerator : IIncrementalGenerator
|
||||
}
|
||||
|
||||
runtimeTypeReference = RuntimeTypeReferenceSpec.FromExternalReflectionLookup(
|
||||
namedType.ContainingAssembly.Identity.Name,
|
||||
namedType.ContainingAssembly.Identity.ToString(),
|
||||
GetReflectionTypeMetadataName(namedType));
|
||||
return true;
|
||||
}
|
||||
@ -396,7 +396,7 @@ public sealed class CqrsHandlerRegistryGenerator : IIncrementalGenerator
|
||||
}
|
||||
|
||||
genericTypeDefinitionReference = RuntimeTypeReferenceSpec.FromExternalReflectionLookup(
|
||||
genericTypeDefinition.ContainingAssembly.Identity.Name,
|
||||
genericTypeDefinition.ContainingAssembly.Identity.ToString(),
|
||||
GetReflectionTypeMetadataName(genericTypeDefinition));
|
||||
return true;
|
||||
}
|
||||
@ -951,28 +951,39 @@ public sealed class CqrsHandlerRegistryGenerator : IIncrementalGenerator
|
||||
if (includeExternalAssemblyTypeLookupHelpers)
|
||||
{
|
||||
builder.AppendLine(
|
||||
" private static global::System.Type? ResolveReferencedAssemblyType(string assemblyName, string typeMetadataName)");
|
||||
" private static global::System.Type? ResolveReferencedAssemblyType(string assemblyIdentity, string typeMetadataName)");
|
||||
builder.AppendLine(" {");
|
||||
builder.AppendLine(" var assembly = ResolveReferencedAssembly(assemblyName);");
|
||||
builder.AppendLine(" var assembly = ResolveReferencedAssembly(assemblyIdentity);");
|
||||
builder.AppendLine(
|
||||
" return assembly?.GetType(typeMetadataName, throwOnError: false, ignoreCase: false);");
|
||||
builder.AppendLine(" }");
|
||||
builder.AppendLine();
|
||||
builder.AppendLine(
|
||||
" private static global::System.Reflection.Assembly? ResolveReferencedAssembly(string assemblyName)");
|
||||
" private static global::System.Reflection.Assembly? ResolveReferencedAssembly(string assemblyIdentity)");
|
||||
builder.AppendLine(" {");
|
||||
builder.AppendLine(" global::System.Reflection.AssemblyName targetAssemblyName;");
|
||||
builder.AppendLine(" try");
|
||||
builder.AppendLine(" {");
|
||||
builder.AppendLine(
|
||||
" targetAssemblyName = new global::System.Reflection.AssemblyName(assemblyIdentity);");
|
||||
builder.AppendLine(" }");
|
||||
builder.AppendLine(" catch");
|
||||
builder.AppendLine(" {");
|
||||
builder.AppendLine(" return null;");
|
||||
builder.AppendLine(" }");
|
||||
builder.AppendLine();
|
||||
builder.AppendLine(
|
||||
" foreach (var assembly in global::System.AppDomain.CurrentDomain.GetAssemblies())");
|
||||
builder.AppendLine(" {");
|
||||
builder.AppendLine(
|
||||
" if (global::System.StringComparer.Ordinal.Equals(assembly.GetName().Name, assemblyName))");
|
||||
" if (global::System.Reflection.AssemblyName.ReferenceMatchesDefinition(targetAssemblyName, assembly.GetName()))");
|
||||
builder.AppendLine(" return assembly;");
|
||||
builder.AppendLine(" }");
|
||||
builder.AppendLine();
|
||||
builder.AppendLine(" try");
|
||||
builder.AppendLine(" {");
|
||||
builder.AppendLine(
|
||||
" return global::System.Reflection.Assembly.Load(new global::System.Reflection.AssemblyName(assemblyName));");
|
||||
" return global::System.Reflection.Assembly.Load(targetAssemblyName);");
|
||||
builder.AppendLine(" }");
|
||||
builder.AppendLine(" catch");
|
||||
builder.AppendLine(" {");
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
using GFramework.SourceGenerators.Diagnostics;
|
||||
using GFramework.Game.SourceGenerators.Diagnostics;
|
||||
|
||||
namespace GFramework.SourceGenerators.Config;
|
||||
namespace GFramework.Game.SourceGenerators.Config;
|
||||
|
||||
/// <summary>
|
||||
/// 根据 AdditionalFiles 中的 JSON schema 生成配置类型和配置表包装。
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
using GFramework.SourceGenerators.Common.Constants;
|
||||
|
||||
namespace GFramework.SourceGenerators.Diagnostics;
|
||||
namespace GFramework.Game.SourceGenerators.Diagnostics;
|
||||
|
||||
/// <summary>
|
||||
/// 提供配置 schema 代码生成相关诊断。
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
<IncludeBuildOutput>false</IncludeBuildOutput>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
|
||||
<CompilerGeneratedFilesOutputPath>Generated</CompilerGeneratedFilesOutputPath>
|
||||
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
using GFramework.SourceGenerators.Analyzers;
|
||||
using GFramework.Core.SourceGenerators.Analyzers;
|
||||
using GFramework.SourceGenerators.Tests.Core;
|
||||
|
||||
namespace GFramework.SourceGenerators.Tests.Analyzers;
|
||||
@ -9,128 +9,128 @@ namespace GFramework.SourceGenerators.Tests.Analyzers;
|
||||
public sealed class ContextRegistrationAnalyzerTests
|
||||
{
|
||||
private const string TestPreamble = """
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace GFramework.Core.Abstractions.Rule
|
||||
{
|
||||
public interface IContextAware { }
|
||||
}
|
||||
namespace GFramework.Core.Abstractions.Rule
|
||||
{
|
||||
public interface IContextAware { }
|
||||
}
|
||||
|
||||
namespace GFramework.Core.Abstractions.Model
|
||||
{
|
||||
public interface IModel : GFramework.Core.Abstractions.Rule.IContextAware { }
|
||||
}
|
||||
namespace GFramework.Core.Abstractions.Model
|
||||
{
|
||||
public interface IModel : GFramework.Core.Abstractions.Rule.IContextAware { }
|
||||
}
|
||||
|
||||
namespace GFramework.Core.Abstractions.Systems
|
||||
{
|
||||
public interface ISystem : GFramework.Core.Abstractions.Rule.IContextAware { }
|
||||
}
|
||||
namespace GFramework.Core.Abstractions.Systems
|
||||
{
|
||||
public interface ISystem : GFramework.Core.Abstractions.Rule.IContextAware { }
|
||||
}
|
||||
|
||||
namespace GFramework.Core.Abstractions.Utility
|
||||
{
|
||||
public interface IUtility : GFramework.Core.Abstractions.Rule.IContextAware { }
|
||||
}
|
||||
namespace GFramework.Core.Abstractions.Utility
|
||||
{
|
||||
public interface IUtility : GFramework.Core.Abstractions.Rule.IContextAware { }
|
||||
}
|
||||
|
||||
namespace GFramework.Core.Abstractions.Architectures
|
||||
{
|
||||
public interface IArchitecture
|
||||
{
|
||||
T RegisterModel<T>(T model) where T : GFramework.Core.Abstractions.Model.IModel;
|
||||
void RegisterModel<T>(Action<T> onCreated = null) where T : class, GFramework.Core.Abstractions.Model.IModel;
|
||||
T RegisterSystem<T>(T system) where T : GFramework.Core.Abstractions.Systems.ISystem;
|
||||
void RegisterSystem<T>(Action<T> onCreated = null) where T : class, GFramework.Core.Abstractions.Systems.ISystem;
|
||||
T RegisterUtility<T>(T utility) where T : GFramework.Core.Abstractions.Utility.IUtility;
|
||||
void RegisterUtility<T>(Action<T> onCreated = null) where T : class, GFramework.Core.Abstractions.Utility.IUtility;
|
||||
IArchitectureModule InstallModule(IArchitectureModule module);
|
||||
}
|
||||
namespace GFramework.Core.Abstractions.Architectures
|
||||
{
|
||||
public interface IArchitecture
|
||||
{
|
||||
T RegisterModel<T>(T model) where T : GFramework.Core.Abstractions.Model.IModel;
|
||||
void RegisterModel<T>(Action<T> onCreated = null) where T : class, GFramework.Core.Abstractions.Model.IModel;
|
||||
T RegisterSystem<T>(T system) where T : GFramework.Core.Abstractions.Systems.ISystem;
|
||||
void RegisterSystem<T>(Action<T> onCreated = null) where T : class, GFramework.Core.Abstractions.Systems.ISystem;
|
||||
T RegisterUtility<T>(T utility) where T : GFramework.Core.Abstractions.Utility.IUtility;
|
||||
void RegisterUtility<T>(Action<T> onCreated = null) where T : class, GFramework.Core.Abstractions.Utility.IUtility;
|
||||
IArchitectureModule InstallModule(IArchitectureModule module);
|
||||
}
|
||||
|
||||
public interface IArchitectureModule
|
||||
{
|
||||
void Install(IArchitecture architecture);
|
||||
}
|
||||
public interface IArchitectureModule
|
||||
{
|
||||
void Install(IArchitecture architecture);
|
||||
}
|
||||
|
||||
public interface IArchitectureContext
|
||||
{
|
||||
TModel GetModel<TModel>() where TModel : class, GFramework.Core.Abstractions.Model.IModel;
|
||||
IReadOnlyList<TModel> GetModels<TModel>() where TModel : class, GFramework.Core.Abstractions.Model.IModel;
|
||||
TSystem GetSystem<TSystem>() where TSystem : class, GFramework.Core.Abstractions.Systems.ISystem;
|
||||
IReadOnlyList<TSystem> GetSystems<TSystem>() where TSystem : class, GFramework.Core.Abstractions.Systems.ISystem;
|
||||
TUtility GetUtility<TUtility>() where TUtility : class, GFramework.Core.Abstractions.Utility.IUtility;
|
||||
IReadOnlyList<TUtility> GetUtilities<TUtility>() where TUtility : class, GFramework.Core.Abstractions.Utility.IUtility;
|
||||
}
|
||||
}
|
||||
public interface IArchitectureContext
|
||||
{
|
||||
TModel GetModel<TModel>() where TModel : class, GFramework.Core.Abstractions.Model.IModel;
|
||||
IReadOnlyList<TModel> GetModels<TModel>() where TModel : class, GFramework.Core.Abstractions.Model.IModel;
|
||||
TSystem GetSystem<TSystem>() where TSystem : class, GFramework.Core.Abstractions.Systems.ISystem;
|
||||
IReadOnlyList<TSystem> GetSystems<TSystem>() where TSystem : class, GFramework.Core.Abstractions.Systems.ISystem;
|
||||
TUtility GetUtility<TUtility>() where TUtility : class, GFramework.Core.Abstractions.Utility.IUtility;
|
||||
IReadOnlyList<TUtility> GetUtilities<TUtility>() where TUtility : class, GFramework.Core.Abstractions.Utility.IUtility;
|
||||
}
|
||||
}
|
||||
|
||||
namespace GFramework.Core.Architectures
|
||||
{
|
||||
public abstract class Architecture : GFramework.Core.Abstractions.Architectures.IArchitecture
|
||||
{
|
||||
protected abstract void OnInitialize();
|
||||
namespace GFramework.Core.Architectures
|
||||
{
|
||||
public abstract class Architecture : GFramework.Core.Abstractions.Architectures.IArchitecture
|
||||
{
|
||||
protected abstract void OnInitialize();
|
||||
|
||||
public virtual T RegisterModel<T>(T model) where T : GFramework.Core.Abstractions.Model.IModel => model;
|
||||
public virtual T RegisterModel<T>(T model) where T : GFramework.Core.Abstractions.Model.IModel => model;
|
||||
|
||||
public virtual void RegisterModel<T>(Action<T> onCreated = null)
|
||||
where T : class, GFramework.Core.Abstractions.Model.IModel
|
||||
{
|
||||
}
|
||||
public virtual void RegisterModel<T>(Action<T> onCreated = null)
|
||||
where T : class, GFramework.Core.Abstractions.Model.IModel
|
||||
{
|
||||
}
|
||||
|
||||
public virtual T RegisterSystem<T>(T system) where T : GFramework.Core.Abstractions.Systems.ISystem => system;
|
||||
public virtual T RegisterSystem<T>(T system) where T : GFramework.Core.Abstractions.Systems.ISystem => system;
|
||||
|
||||
public virtual void RegisterSystem<T>(Action<T> onCreated = null)
|
||||
where T : class, GFramework.Core.Abstractions.Systems.ISystem
|
||||
{
|
||||
}
|
||||
public virtual void RegisterSystem<T>(Action<T> onCreated = null)
|
||||
where T : class, GFramework.Core.Abstractions.Systems.ISystem
|
||||
{
|
||||
}
|
||||
|
||||
public virtual T RegisterUtility<T>(T utility) where T : GFramework.Core.Abstractions.Utility.IUtility => utility;
|
||||
public virtual T RegisterUtility<T>(T utility) where T : GFramework.Core.Abstractions.Utility.IUtility => utility;
|
||||
|
||||
public virtual void RegisterUtility<T>(Action<T> onCreated = null)
|
||||
where T : class, GFramework.Core.Abstractions.Utility.IUtility
|
||||
{
|
||||
}
|
||||
public virtual void RegisterUtility<T>(Action<T> onCreated = null)
|
||||
where T : class, GFramework.Core.Abstractions.Utility.IUtility
|
||||
{
|
||||
}
|
||||
|
||||
public virtual GFramework.Core.Abstractions.Architectures.IArchitectureModule InstallModule(
|
||||
GFramework.Core.Abstractions.Architectures.IArchitectureModule module)
|
||||
{
|
||||
module.Install(this);
|
||||
return module;
|
||||
}
|
||||
}
|
||||
}
|
||||
public virtual GFramework.Core.Abstractions.Architectures.IArchitectureModule InstallModule(
|
||||
GFramework.Core.Abstractions.Architectures.IArchitectureModule module)
|
||||
{
|
||||
module.Install(this);
|
||||
return module;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace GFramework.Core.Extensions
|
||||
{
|
||||
public static class ContextAwareServiceExtensions
|
||||
{
|
||||
public static TModel GetModel<TModel>(this GFramework.Core.Abstractions.Rule.IContextAware contextAware)
|
||||
where TModel : class, GFramework.Core.Abstractions.Model.IModel => throw new NotImplementedException();
|
||||
namespace GFramework.Core.Extensions
|
||||
{
|
||||
public static class ContextAwareServiceExtensions
|
||||
{
|
||||
public static TModel GetModel<TModel>(this GFramework.Core.Abstractions.Rule.IContextAware contextAware)
|
||||
where TModel : class, GFramework.Core.Abstractions.Model.IModel => throw new NotImplementedException();
|
||||
|
||||
public static IReadOnlyList<TModel> GetModels<TModel>(this GFramework.Core.Abstractions.Rule.IContextAware contextAware)
|
||||
where TModel : class, GFramework.Core.Abstractions.Model.IModel => throw new NotImplementedException();
|
||||
public static IReadOnlyList<TModel> GetModels<TModel>(this GFramework.Core.Abstractions.Rule.IContextAware contextAware)
|
||||
where TModel : class, GFramework.Core.Abstractions.Model.IModel => throw new NotImplementedException();
|
||||
|
||||
public static TSystem GetSystem<TSystem>(this GFramework.Core.Abstractions.Rule.IContextAware contextAware)
|
||||
where TSystem : class, GFramework.Core.Abstractions.Systems.ISystem => throw new NotImplementedException();
|
||||
public static TSystem GetSystem<TSystem>(this GFramework.Core.Abstractions.Rule.IContextAware contextAware)
|
||||
where TSystem : class, GFramework.Core.Abstractions.Systems.ISystem => throw new NotImplementedException();
|
||||
|
||||
public static IReadOnlyList<TSystem> GetSystems<TSystem>(this GFramework.Core.Abstractions.Rule.IContextAware contextAware)
|
||||
where TSystem : class, GFramework.Core.Abstractions.Systems.ISystem => throw new NotImplementedException();
|
||||
public static IReadOnlyList<TSystem> GetSystems<TSystem>(this GFramework.Core.Abstractions.Rule.IContextAware contextAware)
|
||||
where TSystem : class, GFramework.Core.Abstractions.Systems.ISystem => throw new NotImplementedException();
|
||||
|
||||
public static TUtility GetUtility<TUtility>(this GFramework.Core.Abstractions.Rule.IContextAware contextAware)
|
||||
where TUtility : class, GFramework.Core.Abstractions.Utility.IUtility => throw new NotImplementedException();
|
||||
public static TUtility GetUtility<TUtility>(this GFramework.Core.Abstractions.Rule.IContextAware contextAware)
|
||||
where TUtility : class, GFramework.Core.Abstractions.Utility.IUtility => throw new NotImplementedException();
|
||||
|
||||
public static IReadOnlyList<TUtility> GetUtilities<TUtility>(this GFramework.Core.Abstractions.Rule.IContextAware contextAware)
|
||||
where TUtility : class, GFramework.Core.Abstractions.Utility.IUtility => throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
public static IReadOnlyList<TUtility> GetUtilities<TUtility>(this GFramework.Core.Abstractions.Rule.IContextAware contextAware)
|
||||
where TUtility : class, GFramework.Core.Abstractions.Utility.IUtility => throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
namespace GFramework.SourceGenerators.Abstractions.Rule
|
||||
{
|
||||
public sealed class GetModelAttribute : Attribute { }
|
||||
public sealed class GetModelsAttribute : Attribute { }
|
||||
public sealed class GetSystemAttribute : Attribute { }
|
||||
public sealed class GetSystemsAttribute : Attribute { }
|
||||
public sealed class GetUtilityAttribute : Attribute { }
|
||||
public sealed class GetUtilitiesAttribute : Attribute { }
|
||||
}
|
||||
""";
|
||||
namespace GFramework.SourceGenerators.Abstractions.Rule
|
||||
{
|
||||
public sealed class GetModelAttribute : Attribute { }
|
||||
public sealed class GetModelsAttribute : Attribute { }
|
||||
public sealed class GetSystemAttribute : Attribute { }
|
||||
public sealed class GetSystemsAttribute : Attribute { }
|
||||
public sealed class GetUtilityAttribute : Attribute { }
|
||||
public sealed class GetUtilitiesAttribute : Attribute { }
|
||||
}
|
||||
""";
|
||||
|
||||
[Test]
|
||||
public async Task Reports_Warning_When_FieldInjectedModel_Is_Not_Registered()
|
||||
@ -366,7 +366,8 @@ public sealed class ContextRegistrationAnalyzerTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Does_Not_Report_When_Inherited_OnInitialize_Calls_Virtual_Helper_Overridden_In_Derived_Architecture()
|
||||
public async Task
|
||||
Does_Not_Report_When_Inherited_OnInitialize_Calls_Virtual_Helper_Overridden_In_Derived_Architecture()
|
||||
{
|
||||
await AnalyzerTestDriver<ContextRegistrationAnalyzer>.RunAsync(
|
||||
Wrap("""
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
using GFramework.SourceGenerators.Architectures;
|
||||
using GFramework.Core.SourceGenerators.Architectures;
|
||||
using GFramework.SourceGenerators.Tests.Core;
|
||||
|
||||
namespace GFramework.SourceGenerators.Tests.Architectures;
|
||||
@ -180,42 +180,42 @@ public class AutoRegisterModuleGeneratorTests
|
||||
""";
|
||||
|
||||
const string partASource = """
|
||||
namespace TestApp
|
||||
{
|
||||
using GFramework.SourceGenerators.Abstractions.Architectures;
|
||||
namespace TestApp
|
||||
{
|
||||
using GFramework.SourceGenerators.Abstractions.Architectures;
|
||||
|
||||
// Padding ensures this attribute lives later in the file than the attributes in PartB.
|
||||
// The generator should still place it first because PartA sorts before PartB.
|
||||
// padding 01
|
||||
// padding 02
|
||||
// padding 03
|
||||
// padding 04
|
||||
// padding 05
|
||||
// padding 06
|
||||
// padding 07
|
||||
// padding 08
|
||||
// padding 09
|
||||
// padding 10
|
||||
[AutoRegisterModule]
|
||||
[RegisterUtility(typeof(AudioUtility))]
|
||||
public partial class GameplayModule
|
||||
{
|
||||
}
|
||||
}
|
||||
""";
|
||||
// Padding ensures this attribute lives later in the file than the attributes in PartB.
|
||||
// The generator should still place it first because PartA sorts before PartB.
|
||||
// padding 01
|
||||
// padding 02
|
||||
// padding 03
|
||||
// padding 04
|
||||
// padding 05
|
||||
// padding 06
|
||||
// padding 07
|
||||
// padding 08
|
||||
// padding 09
|
||||
// padding 10
|
||||
[AutoRegisterModule]
|
||||
[RegisterUtility(typeof(AudioUtility))]
|
||||
public partial class GameplayModule
|
||||
{
|
||||
}
|
||||
}
|
||||
""";
|
||||
|
||||
const string partBSource = """
|
||||
namespace TestApp
|
||||
{
|
||||
using GFramework.SourceGenerators.Abstractions.Architectures;
|
||||
namespace TestApp
|
||||
{
|
||||
using GFramework.SourceGenerators.Abstractions.Architectures;
|
||||
|
||||
[RegisterSystem(typeof(CombatSystem))]
|
||||
[RegisterModel(typeof(PlayerModel))]
|
||||
public partial class GameplayModule
|
||||
{
|
||||
}
|
||||
}
|
||||
""";
|
||||
[RegisterSystem(typeof(CombatSystem))]
|
||||
[RegisterModel(typeof(PlayerModel))]
|
||||
public partial class GameplayModule
|
||||
{
|
||||
}
|
||||
}
|
||||
""";
|
||||
|
||||
const string expected = """
|
||||
// <auto-generated />
|
||||
@ -247,7 +247,8 @@ public class AutoRegisterModuleGeneratorTests
|
||||
},
|
||||
GeneratedSources =
|
||||
{
|
||||
(typeof(AutoRegisterModuleGenerator), "TestApp_GameplayModule.AutoRegisterModule.g.cs", NormalizeLineEndings(expected))
|
||||
(typeof(AutoRegisterModuleGenerator), "TestApp_GameplayModule.AutoRegisterModule.g.cs",
|
||||
NormalizeLineEndings(expected))
|
||||
}
|
||||
},
|
||||
DisabledDiagnostics = { "GF_Common_Trace_001" }
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
using System.IO;
|
||||
using GFramework.SourceGenerators.Bases;
|
||||
using GFramework.Core.SourceGenerators.Bases;
|
||||
using GFramework.SourceGenerators.Tests.Core;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GFramework.SourceGenerators.Tests.Bases;
|
||||
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
using System.Collections.Immutable;
|
||||
using System.IO;
|
||||
using GFramework.SourceGenerators.Config;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using GFramework.Game.SourceGenerators.Config;
|
||||
|
||||
namespace GFramework.SourceGenerators.Tests.Config;
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
using System.Reflection;
|
||||
using GFramework.SourceGenerators.Cqrs;
|
||||
using GFramework.Cqrs.SourceGenerators.Cqrs;
|
||||
using GFramework.SourceGenerators.Tests.Core;
|
||||
|
||||
namespace GFramework.SourceGenerators.Tests.Cqrs;
|
||||
@ -252,6 +252,84 @@ public class CqrsHandlerRegistryGeneratorTests
|
||||
|
||||
""";
|
||||
|
||||
private const string ExternalAssemblyPreciseLookupExpected = """
|
||||
// <auto-generated />
|
||||
#nullable enable
|
||||
|
||||
[assembly: global::GFramework.Cqrs.CqrsHandlerRegistryAttribute(typeof(global::GFramework.Generated.Cqrs.__GFrameworkGeneratedCqrsHandlerRegistry))]
|
||||
|
||||
namespace GFramework.Generated.Cqrs;
|
||||
|
||||
internal sealed class __GFrameworkGeneratedCqrsHandlerRegistry : global::GFramework.Cqrs.ICqrsHandlerRegistry
|
||||
{
|
||||
public void Register(global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::GFramework.Core.Abstractions.Logging.ILogger logger)
|
||||
{
|
||||
if (services is null)
|
||||
throw new global::System.ArgumentNullException(nameof(services));
|
||||
if (logger is null)
|
||||
throw new global::System.ArgumentNullException(nameof(logger));
|
||||
|
||||
var registryAssembly = typeof(global::GFramework.Generated.Cqrs.__GFrameworkGeneratedCqrsHandlerRegistry).Assembly;
|
||||
|
||||
var implementationType0 = typeof(global::TestApp.DerivedHandler);
|
||||
if (implementationType0 is not null)
|
||||
{
|
||||
var serviceType0_0Argument0 = ResolveReferencedAssemblyType("Dependency, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", "Dep.VisibilityScope+ProtectedRequest");
|
||||
var serviceType0_0Argument1Element = ResolveReferencedAssemblyType("Dependency, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", "Dep.VisibilityScope+ProtectedResponse");
|
||||
if (serviceType0_0Argument0 is not null && serviceType0_0Argument1Element is not null)
|
||||
{
|
||||
var serviceType0_0 = typeof(global::GFramework.Cqrs.Abstractions.Cqrs.IRequestHandler<,>).MakeGenericType(serviceType0_0Argument0, serviceType0_0Argument1Element.MakeArrayType());
|
||||
global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddTransient(
|
||||
services,
|
||||
serviceType0_0,
|
||||
implementationType0);
|
||||
logger.Debug("Registered CQRS handler TestApp.DerivedHandler as GFramework.Cqrs.Abstractions.Cqrs.IRequestHandler<Dep.VisibilityScope.ProtectedRequest, Dep.VisibilityScope.ProtectedResponse[]>.");
|
||||
}
|
||||
global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddTransient(
|
||||
services,
|
||||
typeof(global::GFramework.Cqrs.Abstractions.Cqrs.IRequestHandler<global::Dep.VisibleRequest, string>),
|
||||
implementationType0);
|
||||
logger.Debug("Registered CQRS handler TestApp.DerivedHandler as GFramework.Cqrs.Abstractions.Cqrs.IRequestHandler<Dep.VisibleRequest, string>.");
|
||||
}
|
||||
}
|
||||
|
||||
private static global::System.Type? ResolveReferencedAssemblyType(string assemblyIdentity, string typeMetadataName)
|
||||
{
|
||||
var assembly = ResolveReferencedAssembly(assemblyIdentity);
|
||||
return assembly?.GetType(typeMetadataName, throwOnError: false, ignoreCase: false);
|
||||
}
|
||||
|
||||
private static global::System.Reflection.Assembly? ResolveReferencedAssembly(string assemblyIdentity)
|
||||
{
|
||||
global::System.Reflection.AssemblyName targetAssemblyName;
|
||||
try
|
||||
{
|
||||
targetAssemblyName = new global::System.Reflection.AssemblyName(assemblyIdentity);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach (var assembly in global::System.AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
if (global::System.Reflection.AssemblyName.ReferenceMatchesDefinition(targetAssemblyName, assembly.GetName()))
|
||||
return assembly;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return global::System.Reflection.Assembly.Load(targetAssemblyName);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
""";
|
||||
|
||||
/// <summary>
|
||||
/// 验证生成器会为当前程序集中的 request、notification 和 stream 处理器生成稳定顺序的注册器。
|
||||
/// </summary>
|
||||
@ -923,37 +1001,9 @@ public class CqrsHandlerRegistryGeneratorTests
|
||||
contractsReference,
|
||||
dependencyReference);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(
|
||||
generatedSource,
|
||||
Does.Contain("var implementationType0 = typeof(global::TestApp.DerivedHandler);"));
|
||||
Assert.That(
|
||||
generatedSource,
|
||||
Does.Contain(
|
||||
"ResolveReferencedAssemblyType(\"Dependency\", \"Dep.VisibilityScope+ProtectedRequest\")"));
|
||||
Assert.That(
|
||||
generatedSource,
|
||||
Does.Contain(
|
||||
"ResolveReferencedAssemblyType(\"Dependency\", \"Dep.VisibilityScope+ProtectedResponse\")"));
|
||||
Assert.That(
|
||||
generatedSource,
|
||||
Does.Contain(
|
||||
"typeof(global::GFramework.Cqrs.Abstractions.Cqrs.IRequestHandler<global::Dep.VisibleRequest, string>)"));
|
||||
Assert.That(
|
||||
generatedSource,
|
||||
Does.Contain("ResolveReferencedAssembly(string assemblyName)"));
|
||||
Assert.That(
|
||||
generatedSource,
|
||||
Does.Not.Contain("knownServiceTypes0"));
|
||||
Assert.That(
|
||||
generatedSource,
|
||||
Does.Not.Contain("RegisterRemainingReflectedHandlerInterfaces"));
|
||||
Assert.That(
|
||||
generatedSource,
|
||||
Does.Not.Contain(
|
||||
"// Remaining runtime interface discovery target:"));
|
||||
});
|
||||
Assert.That(
|
||||
generatedSource,
|
||||
Is.EqualTo(ExternalAssemblyPreciseLookupExpected));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
using System.IO;
|
||||
using GFramework.SourceGenerators.Enums;
|
||||
using GFramework.Core.SourceGenerators.Enums;
|
||||
using GFramework.SourceGenerators.Tests.Core;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GFramework.SourceGenerators.Tests.Enums;
|
||||
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
using System.IO;
|
||||
using GFramework.SourceGenerators.Logging;
|
||||
using GFramework.Core.SourceGenerators.Logging;
|
||||
using GFramework.SourceGenerators.Tests.Core;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GFramework.SourceGenerators.Tests.Logging;
|
||||
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
using System.IO;
|
||||
using GFramework.SourceGenerators.Rule;
|
||||
using GFramework.Core.SourceGenerators.Rule;
|
||||
using GFramework.SourceGenerators.Tests.Core;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GFramework.SourceGenerators.Tests.Rule;
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
using GFramework.SourceGenerators.Rule;
|
||||
using GFramework.Core.SourceGenerators.Rule;
|
||||
using GFramework.SourceGenerators.Tests.Core;
|
||||
|
||||
namespace GFramework.SourceGenerators.Tests.Rule;
|
||||
|
||||
@ -30,19 +30,18 @@
|
||||
<None Remove="GFramework.Game\**"/>
|
||||
<None Remove="GFramework.Godot\**"/>
|
||||
<None Update="GFramework.Core.SourceGenerators\logging\README.md">
|
||||
<Link>GFramework.SorceGenerators\logging\README.md</Link>
|
||||
<Link>GFramework.Core.SourceGenerators\logging\README.md</Link>
|
||||
</None>
|
||||
<None Update="GFramework.Core.SourceGenerators\README.md">
|
||||
<Link>GFramework.SorceGenerators\README.md</Link>
|
||||
<Link>GFramework.Core.SourceGenerators\README.md</Link>
|
||||
</None>
|
||||
<None Update="GFramework.Core.SourceGenerators\AnalyzerReleases.Shipped.md">
|
||||
<Link>GFramework.SorceGenerators\AnalyzerReleases.Shipped.md</Link>
|
||||
<Link>GFramework.Core.SourceGenerators\AnalyzerReleases.Shipped.md</Link>
|
||||
</None>
|
||||
<None Update="GFramework.Core.SourceGenerators\AnalyzerReleases.Unshipped.md">
|
||||
<Link>GFramework.SorceGenerators\AnalyzerReleases.Unshipped.md</Link>
|
||||
<Link>GFramework.Core.SourceGenerators\AnalyzerReleases.Unshipped.md</Link>
|
||||
</None>
|
||||
<None Remove="GFramework.Godot.SourceGenerators\**"/>
|
||||
<None Remove="GFramework.SorceGenerators\**"/>
|
||||
<None Remove="GFramework.SourceGenerators\**"/>
|
||||
<None Remove="GFramework.Core.SourceGenerators\**"/>
|
||||
<None Remove="GFramework.Core.SourceGenerators.Abstractions\**"/>
|
||||
@ -82,16 +81,15 @@
|
||||
<Compile Remove="GFramework.Game\**"/>
|
||||
<Compile Remove="GFramework.Godot\**"/>
|
||||
<Compile Update="GFramework.Core.SourceGenerators\enums\EnumExtensionsGenerator.cs">
|
||||
<Link>GFramework.SorceGenerators\enums\EnumExtensionsGenerator.cs</Link>
|
||||
<Link>GFramework.Core.SourceGenerators\enums\EnumExtensionsGenerator.cs</Link>
|
||||
</Compile>
|
||||
<Compile Update="GFramework.Core.SourceGenerators\logging\Diagnostic.cs">
|
||||
<Link>GFramework.SorceGenerators\logging\Diagnostic.cs</Link>
|
||||
<Link>GFramework.Core.SourceGenerators\logging\Diagnostic.cs</Link>
|
||||
</Compile>
|
||||
<Compile Update="GFramework.Core.SourceGenerators\logging\LoggerGenerator.cs">
|
||||
<Link>GFramework.SorceGenerators\logging\LoggerGenerator.cs</Link>
|
||||
<Link>GFramework.Core.SourceGenerators\logging\LoggerGenerator.cs</Link>
|
||||
</Compile>
|
||||
<Compile Remove="GFramework.Godot.SourceGenerators\**"/>
|
||||
<Compile Remove="GFramework.SorceGenerators\**"/>
|
||||
<Compile Remove="GFramework.SourceGenerators\**"/>
|
||||
<Compile Remove="GFramework.Core.SourceGenerators\**"/>
|
||||
<Compile Remove="GFramework.Core.SourceGenerators.Abstractions\**"/>
|
||||
@ -126,7 +124,6 @@
|
||||
<EmbeddedResource Remove="GFramework.Game\**"/>
|
||||
<EmbeddedResource Remove="GFramework.Godot\**"/>
|
||||
<EmbeddedResource Remove="GFramework.Godot.SourceGenerators\**"/>
|
||||
<EmbeddedResource Remove="GFramework.SorceGenerators\**"/>
|
||||
<EmbeddedResource Remove="GFramework.SourceGenerators\**"/>
|
||||
<EmbeddedResource Remove="GFramework.Core.SourceGenerators\**"/>
|
||||
<EmbeddedResource Remove="GFramework.Core.SourceGenerators.Abstractions\**"/>
|
||||
|
||||
@ -68,8 +68,11 @@ dotnet add package GeWuYou.GFramework.Game.Abstractions
|
||||
# Godot 集成(仅 Godot 项目需要)
|
||||
dotnet add package GeWuYou.GFramework.Godot
|
||||
|
||||
# 源码生成器(可选,但推荐)
|
||||
dotnet add package GeWuYou.GFramework.SourceGenerators
|
||||
# 按场景选择源码生成器(可选,但推荐)
|
||||
dotnet add package GeWuYou.GFramework.Core.SourceGenerators
|
||||
dotnet add package GeWuYou.GFramework.Game.SourceGenerators
|
||||
dotnet add package GeWuYou.GFramework.Godot.SourceGenerators
|
||||
dotnet add package GeWuYou.GFramework.Cqrs.SourceGenerators
|
||||
```
|
||||
|
||||
## 可选模块导入
|
||||
|
||||
@ -247,6 +247,8 @@ public class GameArchitecture : Architecture
|
||||
handler。
|
||||
|
||||
`RegisterCqrsPipelineBehavior<TBehavior>()` 是唯一保留的公开入口;旧的 `Mediator` 兼容别名与扩展已移除,不再继续维护。
|
||||
如果你正在从旧版本迁移,显式替换关系就是
|
||||
`RegisterMediatorBehavior<TBehavior>() -> RegisterCqrsPipelineBehavior<TBehavior>()`。
|
||||
当前接口支持两种形式:
|
||||
|
||||
- 开放泛型行为,例如 `LoggingBehavior<,>`,用于匹配所有请求
|
||||
|
||||
@ -180,7 +180,9 @@ GameProject/
|
||||
如果你使用打包后的 NuGet,而不是仓库内项目引用,原则保持不变:
|
||||
|
||||
- 运行时项目需要引用 `GeWuYou.GFramework.Game`
|
||||
- 生成器项目需要引用 `GeWuYou.GFramework.SourceGenerators`
|
||||
- 配置 schema 生成器需要引用 `GeWuYou.GFramework.Game.SourceGenerators`
|
||||
- 如果同一项目还会使用 `[Log]`、`[ContextAware]`、`[GetSystem]` 等 Core 侧生成器特性,再额外引用
|
||||
`GeWuYou.GFramework.Core.SourceGenerators`
|
||||
- schema 目录默认仍然是 `schemas/`
|
||||
|
||||
如果你的 schema 不放在默认目录,可以在项目文件里覆盖:
|
||||
|
||||
@ -6,13 +6,18 @@ GFramework 提供多种安装方式,您可以根据项目需求选择合适的
|
||||
|
||||
GFramework 采用模块化设计,不同包提供不同的功能:
|
||||
|
||||
| 包名 | 说明 | 适用场景 |
|
||||
|---------------------------------------|---------|-----------|
|
||||
| `GeWuYou.GFramework` | 聚合元包 | 快速试用、原型开发 |
|
||||
| `GeWuYou.GFramework.Core` | 核心框架 | 生产项目推荐 |
|
||||
| `GeWuYou.GFramework.Game` | 游戏模块 | 需要游戏特定功能 |
|
||||
| `GeWuYou.GFramework.Godot` | Godot集成 | Godot项目必需 |
|
||||
| `GeWuYou.GFramework.SourceGenerators` | 源码生成器 | 推荐安装 |
|
||||
| 包名 | 说明 | 适用场景 |
|
||||
|---------------------------------------------|-------------|--------------------------------|
|
||||
| `GeWuYou.GFramework` | 聚合元包 | 快速试用、原型开发 |
|
||||
| `GeWuYou.GFramework.Core` | 核心框架 | 生产项目推荐 |
|
||||
| `GeWuYou.GFramework.Game` | 游戏模块 | 需要游戏特定功能 |
|
||||
| `GeWuYou.GFramework.Godot` | Godot集成 | Godot项目必需 |
|
||||
| `GeWuYou.GFramework.Core.SourceGenerators` | Core 源码生成器 | `[Log]`、`[ContextAware]`、架构注入等 |
|
||||
| `GeWuYou.GFramework.Game.SourceGenerators` | Game 源码生成器 | 配置 schema / 配表生成 |
|
||||
| `GeWuYou.GFramework.Godot.SourceGenerators` | Godot 源码生成器 | Godot 节点、UI、项目元数据生成 |
|
||||
| `GeWuYou.GFramework.Cqrs.SourceGenerators` | CQRS 源码生成器 | 处理器注册表生成 |
|
||||
|
||||
当前 NuGet 发布按模块拆分 source generator 包,不存在 `GeWuYou.GFramework.SourceGenerators` 聚合包。
|
||||
|
||||
## 安装方式
|
||||
|
||||
@ -30,8 +35,17 @@ dotnet add package GeWuYou.GFramework.Game.Abstractions
|
||||
# Godot 集成(仅 Godot 项目需要)
|
||||
dotnet add package GeWuYou.GFramework.Godot
|
||||
|
||||
# 源码生成器(可选,但推荐)
|
||||
dotnet add package GeWuYou.GFramework.SourceGenerators
|
||||
# Core 侧源码生成器([Log] / [ContextAware] / [GetSystem] 等)
|
||||
dotnet add package GeWuYou.GFramework.Core.SourceGenerators
|
||||
|
||||
# Game 配置 schema 生成器
|
||||
dotnet add package GeWuYou.GFramework.Game.SourceGenerators
|
||||
|
||||
# Godot 生成器(仅 Godot 项目需要)
|
||||
dotnet add package GeWuYou.GFramework.Godot.SourceGenerators
|
||||
|
||||
# CQRS 处理器注册生成器(仅使用 CQRS source generator 时需要)
|
||||
dotnet add package GeWuYou.GFramework.Cqrs.SourceGenerators
|
||||
```
|
||||
|
||||
### 2. 使用 PackageReference
|
||||
@ -56,8 +70,14 @@ dotnet add package GeWuYou.GFramework.SourceGenerators
|
||||
<!-- Godot 集成 -->
|
||||
<PackageReference Include="GeWuYou.GFramework.Godot" Version="1.0.0" />
|
||||
|
||||
<!-- 源码生成器 -->
|
||||
<PackageReference Include="GeWuYou.GFramework.SourceGenerators" Version="1.0.0"
|
||||
<!-- 按场景选择的源码生成器 -->
|
||||
<PackageReference Include="GeWuYou.GFramework.Core.SourceGenerators" Version="1.0.0"
|
||||
PrivateAssets="all" ExcludeAssets="runtime" />
|
||||
<PackageReference Include="GeWuYou.GFramework.Game.SourceGenerators" Version="1.0.0"
|
||||
PrivateAssets="all" ExcludeAssets="runtime" />
|
||||
<PackageReference Include="GeWuYou.GFramework.Godot.SourceGenerators" Version="1.0.0"
|
||||
PrivateAssets="all" ExcludeAssets="runtime" />
|
||||
<PackageReference Include="GeWuYou.GFramework.Cqrs.SourceGenerators" Version="1.0.0"
|
||||
PrivateAssets="all" ExcludeAssets="runtime" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@ -183,6 +203,8 @@ dotnet build
|
||||
|
||||
检查:
|
||||
|
||||
- 确保安装了 `GeWuYou.GFramework.SourceGenerators`
|
||||
- 确保安装了与你正在使用的特性对应的拆分生成器包,例如:
|
||||
`GeWuYou.GFramework.Core.SourceGenerators`、`GeWuYou.GFramework.Game.SourceGenerators`、
|
||||
`GeWuYou.GFramework.Godot.SourceGenerators` 或 `GeWuYou.GFramework.Cqrs.SourceGenerators`
|
||||
- 重启 IDE
|
||||
- 清理并重新构建项目
|
||||
|
||||
@ -30,7 +30,16 @@ GFramework.SourceGenerators 是 GFramework 框架的源代码生成器包,通
|
||||
|
||||
## 概述
|
||||
|
||||
GFramework.SourceGenerators 利用 Roslyn 源代码生成器技术,在编译时分析你的代码并自动生成常用的样板代码,让开发者专注于业务逻辑而不是重复的模板代码。
|
||||
GFramework 的 source generators 利用 Roslyn 源代码生成器技术,在编译时分析你的代码并自动生成常用的样板代码,让开发者专注于业务逻辑而不是重复的模板代码。
|
||||
|
||||
当前 NuGet 发布按模块拆分为:
|
||||
|
||||
- `GeWuYou.GFramework.Core.SourceGenerators`
|
||||
- `GeWuYou.GFramework.Game.SourceGenerators`
|
||||
- `GeWuYou.GFramework.Godot.SourceGenerators`
|
||||
- `GeWuYou.GFramework.Cqrs.SourceGenerators`
|
||||
|
||||
不存在 `GeWuYou.GFramework.SourceGenerators` 或 `GeWuYou.GFramework.SourceGenerators.Attributes` 这类聚合包。
|
||||
|
||||
### 核心设计理念
|
||||
|
||||
@ -74,22 +83,30 @@ GFramework.SourceGenerators 利用 Roslyn 源代码生成器技术,在编译
|
||||
### NuGet 包安装
|
||||
|
||||
```xml
|
||||
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="GeWuYou.GFramework.SourceGenerators" Version="1.0.0"/>
|
||||
<PackageReference Include="GeWuYou.GFramework.SourceGenerators.Attributes" Version="1.0.0"/>
|
||||
<PackageReference Include="GeWuYou.GFramework.Core.SourceGenerators" Version="1.0.0"
|
||||
PrivateAssets="all"
|
||||
ExcludeAssets="runtime" />
|
||||
<PackageReference Include="GeWuYou.GFramework.Game.SourceGenerators" Version="1.0.0"
|
||||
PrivateAssets="all"
|
||||
ExcludeAssets="runtime" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
```
|
||||
|
||||
如果你只使用 Godot 生成器或 CQRS 处理器注册生成器,请把上面的包替换为对应的
|
||||
`GeWuYou.GFramework.Godot.SourceGenerators` 或 `GeWuYou.GFramework.Cqrs.SourceGenerators`。
|
||||
这些拆分包会同时带上各自需要的 abstractions 程序集,不需要再额外安装单独的 `*.Attributes` 包。
|
||||
|
||||
### Config Schema 文件约定
|
||||
|
||||
当项目引用 `GeWuYou.GFramework.SourceGenerators` 的打包产物时,生成器会默认从 `schemas/**/*.schema.json` 收集配置 schema
|
||||
当项目引用 `GeWuYou.GFramework.Game.SourceGenerators` 的打包产物时,生成器会默认从 `schemas/**/*.schema.json` 收集配置
|
||||
schema
|
||||
文件并作为 `AdditionalFiles` 输入。
|
||||
|
||||
这意味着消费者项目通常只需要维护如下结构:
|
||||
@ -150,7 +167,7 @@ Config Schema 生成器会扫描 `*.schema.json` 文件,并生成:
|
||||
### 基础使用
|
||||
|
||||
```csharp
|
||||
using GFramework.SourceGenerators.Attributes;
|
||||
using GFramework.SourceGenerators.Abstractions.Logging;
|
||||
|
||||
[Log]
|
||||
public partial class PlayerController
|
||||
|
||||
@ -74,8 +74,11 @@ dotnet add package GeWuYou.GFramework
|
||||
# Godot 集成
|
||||
dotnet add package GeWuYou.GFramework.Godot
|
||||
|
||||
# 源码生成器(可选,但推荐)
|
||||
dotnet add package GeWuYou.GFramework.SourceGenerators
|
||||
# Core 侧源码生成器([Log] / [ContextAware] 等)
|
||||
dotnet add package GeWuYou.GFramework.Core.SourceGenerators
|
||||
|
||||
# Godot 侧源码生成器([GetNode] / [AutoUiPage] 等)
|
||||
dotnet add package GeWuYou.GFramework.Godot.SourceGenerators
|
||||
```
|
||||
|
||||
::: details 分包安装(了解即可)
|
||||
@ -93,8 +96,11 @@ dotnet add package GeWuYou.GFramework.Game.Abstractions
|
||||
# Godot 集成
|
||||
dotnet add package GeWuYou.GFramework.Godot
|
||||
|
||||
# 源码生成器
|
||||
dotnet add package GeWuYou.GFramework.SourceGenerators
|
||||
# Core 侧源码生成器
|
||||
dotnet add package GeWuYou.GFramework.Core.SourceGenerators
|
||||
|
||||
# Godot 侧源码生成器
|
||||
dotnet add package GeWuYou.GFramework.Godot.SourceGenerators
|
||||
```
|
||||
|
||||
:::
|
||||
@ -108,7 +114,8 @@ dotnet add package GeWuYou.GFramework.SourceGenerators
|
||||
3. 安装以下包:
|
||||
- `GeWuYou.GFramework`
|
||||
- `GeWuYou.GFramework.Godot`
|
||||
- `GeWuYou.GFramework.SourceGenerators`
|
||||
- `GeWuYou.GFramework.Core.SourceGenerators`
|
||||
- `GeWuYou.GFramework.Godot.SourceGenerators`
|
||||
|
||||

|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user