refactor(architecture): 重构架构阶段验证和初始化流程

- 修改阶段转换验证逻辑,允许从任何阶段转换到 FailedInitialization
- 调整初始化流程,确保始终进入各个阶段而不仅仅是有组件时才进入
- 重新排列阶段转换顺序,实现线性状态机模式
- 添加架构阶段线性顺序定义数组
- 更新测试用例以验证初始化失败时抛出异常的情况
This commit is contained in:
GeWuYou 2026-01-17 10:05:52 +08:00
parent 177de6d3e6
commit f70254716b
4 changed files with 92 additions and 53 deletions

View File

@ -1,4 +1,4 @@
using GFramework.Core.Abstractions.enums;
using GFramework.Core.Abstractions.enums;
using GFramework.Core.Tests.architecture;
using GFramework.Core.Tests.model;
using GFramework.Core.Tests.system;
@ -94,7 +94,7 @@ public class AsyncArchitectureTests : ArchitectureTestsBase<AsyncTestArchitectur
{
Architecture!.AddPostRegistrationHook(a => { a.RegisterModel(new FailingModel()); });
await Architecture.InitializeAsync();
Assert.ThrowsAsync<InvalidOperationException>(async () => await Architecture.InitializeAsync());
Assert.That(
Architecture.CurrentPhase,
@ -141,7 +141,7 @@ public class AsyncArchitectureTests : ArchitectureTestsBase<AsyncTestArchitectur
a.RegisterModel(new FailingModel())
);
await Architecture.InitializeAsync();
Assert.ThrowsAsync<InvalidOperationException>(async () => await Architecture.InitializeAsync());
AssertInitializationFailed();
}

View File

@ -1,4 +1,3 @@
using System;
using GFramework.Core.Abstractions.enums;
using GFramework.Core.architecture;
using GFramework.Core.Tests.architecture;
@ -137,7 +136,7 @@ public class SyncArchitectureTests : ArchitectureTestsBase<SyncTestArchitecture>
a.RegisterModel(new FailingModel())
);
Architecture.Initialize();
Assert.Throws<InvalidOperationException>(() => Architecture.Initialize());
AssertInitializationFailed();
}

View File

@ -134,6 +134,7 @@ public abstract class Architecture(
#region Lifecycle Management
// ==================== 方案1: 早期返回 (推荐) ====================
/// <summary>
/// 进入指定的架构阶段,并执行相应的生命周期管理操作
/// </summary>
@ -141,29 +142,57 @@ public abstract class Architecture(
/// <exception cref="InvalidOperationException">当阶段转换不被允许时抛出异常</exception>
protected virtual void EnterPhase(ArchitecturePhase next)
{
if (Configuration.ArchitectureProperties.StrictPhaseValidation &&
(!ArchitectureConstants.PhaseTransitions.TryGetValue(CurrentPhase, out var allowed) ||
!allowed.Contains(next)))
{
// 验证阶段转换是否合法
var errorMsg = $"Invalid phase transition: {CurrentPhase} -> {next}";
_logger.Fatal(errorMsg);
throw new InvalidOperationException(errorMsg);
}
// 验证阶段转换
ValidatePhaseTransition(next);
// 执行阶段转换
var previousPhase = CurrentPhase;
CurrentPhase = next;
if (previousPhase != next)
_logger.Info($"Architecture phase changed: {previousPhase} -> {next}");
// 通知阶段变更
NotifyPhase(next);
NotifyPhaseAwareObjects(next);
}
// 通知所有架构阶段感知对象阶段变更
/// <summary>
/// 验证阶段转换是否合法
/// </summary>
/// <param name="next">目标阶段</param>
/// <exception cref="InvalidOperationException">当阶段转换不合法时抛出</exception>
private void ValidatePhaseTransition(ArchitecturePhase next)
{
// 不需要严格验证,直接返回
if (!Configuration.ArchitectureProperties.StrictPhaseValidation)
return;
// FailedInitialization 可以从任何阶段转换,直接返回
if (next == ArchitecturePhase.FailedInitialization)
return;
// 检查转换是否在允许列表中
if (ArchitectureConstants.PhaseTransitions.TryGetValue(CurrentPhase, out var allowed) &&
allowed.Contains(next))
return;
// 转换不合法,抛出异常
var errorMsg = $"Invalid phase transition: {CurrentPhase} -> {next}";
_logger.Fatal(errorMsg);
throw new InvalidOperationException(errorMsg);
}
/// <summary>
/// 通知所有架构阶段感知对象阶段变更
/// </summary>
/// <param name="phase">新阶段</param>
private void NotifyPhaseAwareObjects(ArchitecturePhase phase)
{
foreach (var obj in Container.GetAll<IArchitecturePhaseAware>())
{
_logger.Trace($"Notifying phase-aware object {obj.GetType().Name} of phase change to {next}");
obj.OnArchitecturePhase(next);
_logger.Trace($"Notifying phase-aware object {obj.GetType().Name} of phase change to {phase}");
obj.OnArchitecturePhase(phase);
}
}
@ -232,10 +261,11 @@ public abstract class Architecture(
var models = _pendingInitializableList.OfType<IModel>().ToList();
var systems = _pendingInitializableList.OfType<ISystem>().ToList();
// 1. 初始化工具
// 1. 工具初始化阶段(始终进入阶段,仅在有组件时执行初始化)
EnterPhase(ArchitecturePhase.BeforeUtilityInit);
if (utilities.Count != 0)
{
EnterPhase(ArchitecturePhase.BeforeUtilityInit);
_logger.Info($"Initializing {utilities.Count} context utilities");
foreach (var utility in utilities)
@ -244,14 +274,16 @@ public abstract class Architecture(
await InitializeComponentAsync(utility, asyncMode);
}
EnterPhase(ArchitecturePhase.AfterUtilityInit);
_logger.Info("All context utilities initialized");
}
// 2. 初始化模型
EnterPhase(ArchitecturePhase.AfterUtilityInit);
// 2. 模型初始化阶段(始终进入阶段,仅在有组件时执行初始化)
EnterPhase(ArchitecturePhase.BeforeModelInit);
if (models.Count != 0)
{
EnterPhase(ArchitecturePhase.BeforeModelInit);
_logger.Info($"Initializing {models.Count} models");
foreach (var model in models)
@ -260,14 +292,16 @@ public abstract class Architecture(
await InitializeComponentAsync(model, asyncMode);
}
EnterPhase(ArchitecturePhase.AfterModelInit);
_logger.Info("All models initialized");
}
// 3. 初始化系统
EnterPhase(ArchitecturePhase.AfterModelInit);
// 3. 系统初始化阶段(始终进入阶段,仅在有组件时执行初始化)
EnterPhase(ArchitecturePhase.BeforeSystemInit);
if (systems.Count != 0)
{
EnterPhase(ArchitecturePhase.BeforeSystemInit);
_logger.Info($"Initializing {systems.Count} systems");
foreach (var system in systems)
@ -276,10 +310,11 @@ public abstract class Architecture(
await InitializeComponentAsync(system, asyncMode);
}
EnterPhase(ArchitecturePhase.AfterSystemInit);
_logger.Info("All systems initialized");
}
EnterPhase(ArchitecturePhase.AfterSystemInit);
_pendingInitializableList.Clear();
_logger.Info("All components initialized");
}

View File

@ -1,4 +1,4 @@
using System.Collections.Immutable;
using System.Collections.Immutable;
using GFramework.Core.Abstractions.enums;
namespace GFramework.Core.architecture;
@ -8,42 +8,47 @@ namespace GFramework.Core.architecture;
/// </summary>
public static class ArchitectureConstants
{
/// <summary>
/// 定义架构阶段的线性顺序
/// </summary>
/// <remarks>
/// 架构阶段永远按照此顺序线性进行,无论是否有组件注册
/// </remarks>
public static readonly ArchitecturePhase[] PhaseOrder =
[
ArchitecturePhase.None,
ArchitecturePhase.BeforeUtilityInit,
ArchitecturePhase.AfterUtilityInit,
ArchitecturePhase.BeforeModelInit,
ArchitecturePhase.AfterModelInit,
ArchitecturePhase.BeforeSystemInit,
ArchitecturePhase.AfterSystemInit,
ArchitecturePhase.Ready,
ArchitecturePhase.Destroying,
ArchitecturePhase.Destroyed
];
/// <summary>
/// 定义架构阶段之间的有效转换关系
/// </summary>
/// <remarks>
/// 键为当前架构阶段,值为从该阶段可以转换到的下一阶段数组
/// 架构采用线性状态机模式,只允许顺序转换,但允许从任何阶段转到 FailedInitialization
/// </remarks>
public static readonly ImmutableDictionary<ArchitecturePhase, ArchitecturePhase[]> PhaseTransitions =
new Dictionary<ArchitecturePhase, ArchitecturePhase[]>
{
// 正常线性流程
{ ArchitecturePhase.None, [ArchitecturePhase.BeforeUtilityInit] },
{
ArchitecturePhase.BeforeUtilityInit,
[ArchitecturePhase.AfterUtilityInit, ArchitecturePhase.FailedInitialization]
},
{
ArchitecturePhase.AfterUtilityInit,
[ArchitecturePhase.BeforeModelInit, ArchitecturePhase.FailedInitialization]
},
{
ArchitecturePhase.BeforeModelInit, [
ArchitecturePhase.AfterModelInit, ArchitecturePhase.FailedInitialization
]
},
{
ArchitecturePhase.AfterModelInit, [
ArchitecturePhase.BeforeSystemInit, ArchitecturePhase.FailedInitialization
]
},
{
ArchitecturePhase.BeforeSystemInit, [
ArchitecturePhase.AfterSystemInit, ArchitecturePhase.FailedInitialization
]
},
{ ArchitecturePhase.AfterSystemInit, [ArchitecturePhase.Ready, ArchitecturePhase.FailedInitialization] },
{ ArchitecturePhase.BeforeUtilityInit, [ArchitecturePhase.AfterUtilityInit] },
{ ArchitecturePhase.AfterUtilityInit, [ArchitecturePhase.BeforeModelInit] },
{ ArchitecturePhase.BeforeModelInit, [ArchitecturePhase.AfterModelInit] },
{ ArchitecturePhase.AfterModelInit, [ArchitecturePhase.BeforeSystemInit] },
{ ArchitecturePhase.BeforeSystemInit, [ArchitecturePhase.AfterSystemInit] },
{ ArchitecturePhase.AfterSystemInit, [ArchitecturePhase.Ready] },
{ ArchitecturePhase.Ready, [ArchitecturePhase.Destroying] },
{ ArchitecturePhase.FailedInitialization, [ArchitecturePhase.Destroying] },
{ ArchitecturePhase.Destroying, [ArchitecturePhase.Destroyed] }
{ ArchitecturePhase.Destroying, [ArchitecturePhase.Destroyed] },
// 失败路径:从任何阶段都可以转到 FailedInitialization
{ ArchitecturePhase.FailedInitialization, [ArchitecturePhase.Destroying] }
}.ToImmutableDictionary();
}