refactor(context): 重构上下文管理实现

- 引入 IArchitectureContextProvider 接口解耦上下文获取逻辑
- 创建 GameContextProvider 作为默认上下文提供者
- 添加 ScopedContextProvider 支持多架构实例场景
- 修改源代码生成器使用上下文提供者模式
- 增加 SetContextProvider 方法支持测试和多架构场景
- 添加 RegistryInitializationHookBase 简化注册表初始化逻辑
This commit is contained in:
GeWuYou 2026-02-28 10:39:36 +08:00 committed by gewuyou
parent f98c7f16cf
commit 0ed8edf015
5 changed files with 165 additions and 3 deletions

View File

@ -0,0 +1,21 @@
namespace GFramework.Core.Abstractions.architecture;
/// <summary>
/// 架构上下文提供者接口,用于解耦上下文获取逻辑
/// </summary>
public interface IArchitectureContextProvider
{
/// <summary>
/// 获取当前的架构上下文
/// </summary>
/// <returns>架构上下文实例</returns>
IArchitectureContext GetContext();
/// <summary>
/// 尝试获取指定类型的架构上下文
/// </summary>
/// <typeparam name="T">架构上下文类型</typeparam>
/// <param name="context">输出的上下文实例</param>
/// <returns>如果成功获取则返回true否则返回false</returns>
bool TryGetContext<T>(out T? context) where T : class, IArchitectureContext;
}

View File

@ -0,0 +1,29 @@
using GFramework.Core.Abstractions.architecture;
namespace GFramework.Core.architecture;
/// <summary>
/// 基于 GameContext 的默认上下文提供者
/// </summary>
public sealed class GameContextProvider : IArchitectureContextProvider
{
/// <summary>
/// 获取当前的架构上下文(返回第一个注册的架构上下文)
/// </summary>
/// <returns>架构上下文实例</returns>
public IArchitectureContext GetContext()
{
return GameContext.GetFirstArchitectureContext();
}
/// <summary>
/// 尝试获取指定类型的架构上下文
/// </summary>
/// <typeparam name="T">架构上下文类型</typeparam>
/// <param name="context">输出的上下文实例</param>
/// <returns>如果成功获取则返回true否则返回false</returns>
public bool TryGetContext<T>(out T? context) where T : class, IArchitectureContext
{
return GameContext.TryGet(out context);
}
}

View File

@ -0,0 +1,55 @@
using GFramework.Core.Abstractions.architecture;
using GFramework.Core.Abstractions.enums;
using GFramework.Core.Abstractions.utility;
namespace GFramework.Core.architecture;
/// <summary>
/// 注册表初始化钩子抽象基类,简化注册表配置的初始化逻辑
/// </summary>
/// <typeparam name="TRegistry">注册表类型</typeparam>
/// <typeparam name="TConfig">配置类型</typeparam>
public abstract class RegistryInitializationHookBase<TRegistry, TConfig> : IArchitectureLifecycleHook
where TRegistry : class, IUtility
{
private readonly IEnumerable<TConfig> _configs;
private readonly ArchitecturePhase _targetPhase;
/// <summary>
/// 初始化注册表初始化钩子
/// </summary>
/// <param name="configs">配置集合</param>
/// <param name="targetPhase">目标执行阶段,默认为 AfterSystemInit</param>
protected RegistryInitializationHookBase(
IEnumerable<TConfig> configs,
ArchitecturePhase targetPhase = ArchitecturePhase.AfterSystemInit)
{
_configs = configs;
_targetPhase = targetPhase;
}
/// <summary>
/// 当架构进入指定阶段时触发的回调方法
/// </summary>
/// <param name="phase">当前的架构阶段</param>
/// <param name="architecture">相关的架构实例</param>
public void OnPhase(ArchitecturePhase phase, IArchitecture architecture)
{
if (phase != _targetPhase) return;
var registry = architecture.Context.GetUtility<TRegistry>();
if (registry == null) return;
foreach (var config in _configs)
{
RegisterConfig(registry, config);
}
}
/// <summary>
/// 注册单个配置项到注册表
/// </summary>
/// <param name="registry">注册表实例</param>
/// <param name="config">配置项</param>
protected abstract void RegisterConfig(TRegistry registry, TConfig config);
}

View File

@ -0,0 +1,44 @@
using GFramework.Core.Abstractions.architecture;
namespace GFramework.Core.architecture;
/// <summary>
/// 作用域上下文提供者,用于多架构实例场景
/// </summary>
public sealed class ScopedContextProvider : IArchitectureContextProvider
{
private readonly IArchitectureContext _context;
/// <summary>
/// 初始化作用域上下文提供者
/// </summary>
/// <param name="context">要绑定的架构上下文实例</param>
public ScopedContextProvider(IArchitectureContext context)
{
_context = context;
}
/// <summary>
/// 获取当前的架构上下文
/// </summary>
/// <returns>架构上下文实例</returns>
public IArchitectureContext GetContext() => _context;
/// <summary>
/// 尝试获取指定类型的架构上下文
/// </summary>
/// <typeparam name="T">架构上下文类型</typeparam>
/// <param name="context">输出的上下文实例</param>
/// <returns>如果成功获取则返回true否则返回false</returns>
public bool TryGetContext<T>(out T? context) where T : class, IArchitectureContext
{
if (_context is T typedContext)
{
context = typedContext;
return true;
}
context = null;
return false;
}
}

View File

@ -121,7 +121,7 @@ public sealed class ContextAwareGenerator : MetadataAttributeClassGeneratorBase
}
// =========================
// Context 属性(无 global::,与测试一致
// Context 属性(使用 IArchitectureContextProvider
// =========================
/// <summary>
/// 生成Context属性
@ -130,9 +130,11 @@ public sealed class ContextAwareGenerator : MetadataAttributeClassGeneratorBase
private static void GenerateContextProperty(StringBuilder sb)
{
sb.AppendLine(" private global::GFramework.Core.Abstractions.architecture.IArchitectureContext? _context;");
sb.AppendLine(
" private static global::GFramework.Core.Abstractions.architecture.IArchitectureContextProvider? _contextProvider;");
sb.AppendLine();
sb.AppendLine(" /// <summary>");
sb.AppendLine(" /// 自动获取的架构上下文(懒加载,默认使用第一个架构");
sb.AppendLine(" /// 自动获取的架构上下文(懒加载,默认使用 GameContextProvider");
sb.AppendLine(" /// </summary>");
sb.AppendLine(" protected global::GFramework.Core.Abstractions.architecture.IArchitectureContext Context");
sb.AppendLine(" {");
@ -141,13 +143,24 @@ public sealed class ContextAwareGenerator : MetadataAttributeClassGeneratorBase
sb.AppendLine(" if (_context == null)");
sb.AppendLine(" {");
sb.AppendLine(
" _context = global::GFramework.Core.architecture.GameContext.GetFirstArchitectureContext();");
" _contextProvider ??= new global::GFramework.Core.architecture.GameContextProvider();");
sb.AppendLine(" _context = _contextProvider.GetContext();");
sb.AppendLine(" }");
sb.AppendLine();
sb.AppendLine(" return _context;");
sb.AppendLine(" }");
sb.AppendLine(" }");
sb.AppendLine();
sb.AppendLine(" /// <summary>");
sb.AppendLine(" /// 配置上下文提供者(用于测试或多架构场景)");
sb.AppendLine(" /// </summary>");
sb.AppendLine(" /// <param name=\"provider\">上下文提供者实例</param>");
sb.AppendLine(
" public static void SetContextProvider(global::GFramework.Core.Abstractions.architecture.IArchitectureContextProvider provider)");
sb.AppendLine(" {");
sb.AppendLine(" _contextProvider = provider;");
sb.AppendLine(" }");
sb.AppendLine();
}